home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-02-03 | 139.8 KB | 4,648 lines | [TEXT/MPS ] |
- æKY CopyrightNotice
- æC Copyright GRAME, Inc. 1989-1993.
- Marketed under exclusif licence by TIME TECH
- Time Tech
- BP 256
- 69659 VILLEFRANCHE Cedex
- France
- All right reserved worlwide
- 411 - MidiShare Help version 1.67
- Mercredi 3 Février 1993 18:34:40
-
- æKY Help
- MidiShareHelp
- æKL Foreword
- About_MidiShare
- Opening_Closing
- Communications
- Sending_Receiving
- Event_managing
- Sequence_managing
- Real_time_tasks
- Synchronisation
- Typology
- Data_structure
- Error_Codes
- Change_Codes
-
- MidiAddField
- MidiAddSeq
- MidiApplySeq
- MidiAvailEv
- MidiCall
- MidiClearSeq
- MidiClose
- MidiConnect
- MidiCopyEv
- MidiCountAppls
- MidiCountDTasks
- MidiCountEvs
- MidiCountFields
- MidiDTask
- MidiExec1DTask
- MidiExt2IntTime
- MidiFlushDTasks
- MidiFlushEvs
- MidiForgetTask
- MidiFreeCell
- MidiFreeEv
- MidiFreeSeq
- MidiFreeSpace
- MidiGetApplAlarm
- MidiGetEv
- MidiGetExtTime
- MidiGetField
- MidiGetFilter
- MidiGetIndAppl
- MidiGetInfo
- MidiGetName
- MidiGetNamedAppl
- MidiGetPortState
- MidiGetRcvAlarm
- MidiGetSyncInfo
- MidiGetTime
- MidiGetVersion
- MidiGrowSpace
- MidiInt2ExtTime
- MidiIsConnected
- MidiNewCell
- MidiNewEv
- MidiNewSeq
- MidiOpen
- MidiReadSync
- MidiSend
- MidiSendAt
- MidiSendIm
- MidiSetApplAlarm
- MidiSetField
- MidiSetFilter
- MidiSetInfo
- MidiSetName
- MidiSetPortState
- MidiSetRcvAlarm
- MidiSetSyncMode
- MidiShare
- MidiSmpte2Time
- MidiTask
- MidiTime2Smpte
- MidiTotalSpace
- MidiWriteSync
-
- typeActiveSens
- typeChanPress
- typeClock
- typeContinue
- typeCopyrigth
- typeCtrl14b
- typeCtrlChange
- typeChanPrefix
- typeCuePoint
- typeDProcess
- typeEndTrack
- typeInstrName
- typeKeyOff
- typeKeyOn
- typeKeyPress
- typeKeySign
- typeLyric
- typeMarker
- typeNonRegParam
- typeNote
- typePitchWheel
- typePrivate
- typeProcess
- typeProgChange
- typeQuarterFrame
- typeRegParam
- typeReserved
- typeReset
- typeSeqName
- typeSeqNum
- typeSMPTEOffset
- typeSongPos
- typeSongSel
- typeSpecific
- typeStart
- typeStop
- typeStream
- typeSysEx
- typeTempo
- typeText
- typeTimeSign
- typeTune
-
-
-
- æKY Foreword
- æC
-
- MidiShare is a multi-tasking, real-time MIDI operating system, specially devised
- for the developing of MIDI applications with a triple target :
-
- •To propose solutions to currently met problems when developing any MIDI application
- : MIDI communication, synchronisation and time management, task management, and
- memory management.
-
- •To enable the real-time and multi-tasking functioning of these applications, i.e.
- to enable the sharing of all the necessary resources and their simultaneous access.
-
- •To make easier cooperation between independent MIDI applications by proposing
- a real-time mechanism of inter-application communications.
-
- The present document is intended for developers who wish to use MidiShare for the
- writing of MIDI applications. They will find here a complete description of all
- the MidiShare functions and procedures, as well as all the data structures in use.
-
- Yann Orlarey and Hervé Lequay
-
-
-
-
-
-
-
-
- æKY About_MidiShare
- æC
-
- The availability of multi-tasking operating systems such as Multi-Finder, Unix
- and OS/2 on microcomputers is a decisive advantage in many application areas and
- offers real gains in term of power and ease of use.
-
- Unfortunately, until now musicians have hardly benefited at all from the advantages
- of such systems due to the lack of music applications capable of running simultaneously
- in real time on a single machine. The internal layers of a Midi program often
- make use of critical resources of the computer such as timers, interrupts and serial
- link controllers which cannot be directly shared by more than one application,
- in addition, even multi-tasking operating systems are not generally a guarantee
- that applications run in real time.
-
- MidiShare came into existence from this observation with the ambition to provide
- the frame needed to develop musical applications in a multi-tasks and real time
- context. When defining MidiShare, we have tried to conciliate three aims :
-
- • To propose solutions to the problems regularly met with in the development of
- all Midi applications.
-
- • To permit the simultaneous running of these applications, especially as regards
- real-time routines and Midi communications.
-
- • To allow for a cooperation between separately developed applications.
-
- We are going to see how the various tools and services proposed by MidiShare comply
- with these objectives.
-
- Events Managing
-
- The whole system is based on the notion of event. An event is a dated entity possessing
- the informations for its own execution. The applications developed with MidiShare
- heavily relie on events to transmit and receive Midi messages but also to remember
- the tasks to be carried out.
-
- It is generally not possible to use the host Operating System Memory Manager (MM)
- to deal with the allocation-deallocation of these events, since it revealed unadapted
- to a real-time context, non reentrant and inefficient, in terms of memory space
- when dealing with small zones of a few bytes.
-
- To make up for these lacks, MidiShare has its own dynamic memory allocation module,
- adapted to real-time constraints. For example, some functions permit to create
- or delete events (under interrupt too) with an extremely brief and constant time
- response. Moreover, these events can be accessed to and handled in a uniform and
- orthogonal way by a small number of routines which take automatically in charge
- the various memory structures (for, let us say, a constant size Key On and a variable
- size System Exclusive).
-
- Communicating
-
- The second essential point is the communications achievement. The applications
- running under MidiShare are not in charge of the communications physical execution
- but only deal with receiving and sending high-level events, for instance, complete
- Midi messages. In fact, MidiShare is internally in charge of translating events
- into corresponding Midi bytes sequences. Each application receives events into
- its own reception fifo. The application can consult this fifo anytime, extract
- and process the events waiting for treatment. Sending out events is easy as well.
- Stating the required output time and event to be transmitted will be sufficient.
-
-
- Midi multiple ports can of course be used. On some softwares, Midi Channels are
- numbered from 0 to 31 so as to take into account the two ports which can be used
- on Macintosh computers. We thought preferable to separate these two informations.
- This way, each MidiShare event has a channel number from 0 to 15 and a port number
- from 0 to 255; in the future, this will permit to deal with numerous Midi lines.
-
- Time managing
-
- It is obvious that a precise time control is essential for music. It is obvious
- too that according to the type of musical work carried out, different time representations
- are needed; which is why we chose the well-tried general solution consisting in
- an absolute representation of time in milliseconds over which other more "musical"
- representations can be built up by applications.
-
- A 32 bits field defines the time for each MidiShare event. This field mentions
- the arrival time for the events received by an application or the required transmission
- time for events sent out by an application.
-
- The algorithm used to manage the events scheduling is of course critical to the
- system’s performances. Several methods have been proposed. In this particular case,
- we have used an algorithm developed at first by one of the authors for MidiLisp.
- This very efficient algorithm ensures in all cases a bounded scheduling and dispatching
- time for treated events.
-
- MidiShare can be synchronised to external Midi Time Code. In this case the MidiShare
- internal time unit accuratly follow the speed variations of the external Midi Time
- Code. Midi applications can be automatically informed when MidiShare start and
- stop being locked to external Midi Time Code.
-
-
- Tasks managing
-
- Not only Midi messages are managed by MidiShare. Actually, an application having
- to remind a task to be done at a precise moment, can send to itself a particular
- type of message containing all the informations required for this task to be carried
- out. When arrived at maturity, this internal event is set by MidiShare in the application’s
- reception fifo as if it were an external event. The application’s reception routine
- will then accomplish the required task.
-
- A second mechanism is implemented by MidiShare for tasks management. It is much
- more "procedural" and actually, very similar to Moxie’s "cause". It is in fact
- a delayed procedure call. For this to be done, MidiShare collects all the call
- parameters, together with the address of the routine to be called and generates
- a specific internal event. When this event has come to maturity, MidiShare restores
- the application context and actually deals with the call. It is to be noted that
- this call is made under interrupts, which means that some precautions have to be
- taken.
-
- A third point related with tasks managing is the possibility for an application
- to define a reception alarm. It is a routine whose application gives MidiShare
- the address and which will be called each time new events are received (see example).
- Alarms therefore avoid an application having to consult periodically its reception
- fifo. Moreover, being called under interrupts, they allow for very efficient time
- responses.
-
- Linking applications
-
- As explained in the introduction, the reason for the creation of MidiShare was
- to permit several independent Midi applications to run simultaneously and to collaborate
- if necessary. This target may initially seem paradoxical. On the one hand, giving
- every application the impression to be the only user of the computer and consequently
- lessening the applications common resources. On the other hand, trying to connect
- these applications.
-
- To isolate the applications was not a very difficult task. For instance, as regards
- incoming Midi messages, each application receives a different copy of them. Beside,
- every application possesses its own filters and reception fifo. There are no problems
- either to merge the various message transmissions, since they occur at the logical
- level too. Finally, as regards time, all applications refer to the same absolute
- clock in milliseconds, without having any influence on it.
-
- How can we now link these applications ? Many users undoubtedly experienced Midi
- informations transfers, of musical sequences for instance, between two computers.
- We have taken over this idea and implemented inside MidiShare an internal real-time
- communication mechanism between applications.
-
- Let us take a concrete example: two applications, the first being an echo generator,
- the second a sequencer. By default, these two applications are connected to the
- actual Midi I/O. However, it is quite possible to connect the output of the echo
- generator to the input of the sequencer. Each application is not aware of the connection
- change.
-
- There is no constraint in the way to connect applications between themselves. In
- particular, it is possible for an application to have multiple sources and multiple
- destinations, or else to be connected to itself (for example a sequencer recording
- itself). Furthermore, these connections can be dynamically reconfigured while the
- applications are running.
-
-
- æKY Opening_Closing
- æC
-
- First of all, an application must make sure that MidiShare is in memory. This checking
- is done thanks to the MidiShare function.
-
- Then, you must call the MidiOpen installation function. This routine allows to
- record some information relative to the application context (its name, the value
- of A5 register, etc...), to affect a reception FIFO and to attribute a unique reference
- number to the application.
-
- As a counterpart to any MidiOpen call, the application must call the MidiClose
- function before leaving, by giving its reference number as an argument. MidiShare
- can thus be aware of the precise number of active Midi applications. In theory,
- there is no objection to an application doing several MidiOpen, under the condition
- it realizes as many MidiClose. In all, there must not be more than 63 simultaneously
- opened Midi applications .
-
- As long as no MidiOpen application is done, MidiShare is asleep and has no influence
- on the computer functioning. Following the first MidiOpen, MidiShare becomes active,
- it creates a task which will be called by an interruption every millisecond,
- then it initiates Acia interruption vectors and registers corresponding to
- Midi ports. MidiShare returns inactive after the last MidiClose.
-
- æKY Communications
- æC
-
- For an application to be able to emit and receive events, it must first connect
- to a source and a destination. In fact, MidiShare is built on an internal communication
- mechanism allowing to exchange in real-time Midi events between active applications.
- An application is like a black box, receiving a flow of events in entry and producing
- a flow of events in output. This black box can be freely connected to other black
- boxes, thus forming an arbitrary complex network. This is one of the major points
- of MidiShare, that allows a form of transparent and powerful collaboration between
- applications otherwise totally independent.
-
- "Real" Midi ins and outs are represented by a pseudo-application, which is always
- refereed to as number 0 and named "MidiShare", with which you just have to connect
- to communicate with the outside.
-
- The implementation of these connections is very simple. The MidiConnect procedure
- allows to switch on or off a connection between a source application and a destination
- application. The MidiIsConnected function gives the state (on or off) of a connection.
- There is no restriction to the establishing of connections, an application can
- be source or destination as many times as you wish. Loops are permitted.
-
- In some special cases, it is important that an application may get information
- on the other active MidiShare applications. The MidiCountAppls function gives the
- number of open Midi applications. The MidiGetIndAppl function allows to know the
- reference number of any application by giving its order number (included between
- 1 and MidiCountAppls). It is also possible to find the reference number of an application
- thanks to its name using the MidiGetNamedAppl function. In the same way, knowing
- an application reference number, it is possible to find its name using the MidiGetName
- function. At last, the MidiSetName procedure allows to change the name of an application.
-
- To be able to write more easily some "meta-applications" for the management of
- connections and other applications, permanent information on context modifications
- into MidiShare (opening of new applications, changing connections, etc...) is
- highly requested. To do so, you just have to define a context alarm thanks to
- MidiSetApplAlarm and MidiGetApplAlarm routines. This alarm will be automatically
- called by MidiShare to inform the application of all the occurred changes.
-
- æKY Sending_Receiving
- æC
-
- Once the connections have been established, the application can send and receive
- Midi events. Each application owns a reception fifo in which MidiShare puts a
- copy of the received events. These come from other applications or from the different
- Midi ports in activity. MidiShare can in theory handle up to 256 ports. The implementation
- of Midi ports is controlled by the MidiSetPortState and MidiGetPortState routines.
- These must be used with care since they affect all the applications.
-
- The MidiCountEvs function allows at any moment to know the number of events waiting
- in the reception fifo. This number is only limited by the memory size available
- for MidiShare. The events at disposal are picked up by repeated appeals to MidiGetEv
- function. The MidiAvailEv function is almost similar. It allows to read a received
- event, while leaving it in the fifo. The MidiFlushEvs procedure eliminates all
- the events on wait in the reception fifo.
-
- The events received by an application are copies. The application can therefore
- freely dispose of them without any repercussion on the other applications. However,
- it must not forget to free them when it no longer needs them.
-
- Each application can select the events to be received by using a filter. The filtering
- process is local to the application and has no influence on the events received
- by the other applications. The implementation of these filters is achieved by two
- routines : MidiSetFilter and MidiGetFilter.
-
- MidiShare drives an internal absolute clock on 32 bits which is automatically switched
- on with the first MidiOpen and keeps running until the last MidiClose. This clock
- is used to date (in milliseconds) all the received events, as well as to specify
- the sending dates of events to be transmitted. Moreover, it provides all the applications
- with an absolute time reference. Its value can be read by the MidiGetTime function.
-
-
- Three routines allow to manage the transmissions. The MidiSendIm procedure allows
- the immediate emission of an event. The MidiSend and MidiSendAt procedures allow
- time delayed emissions, MidiShare automatically taking in charge the effective
- emissions at the scheduled time (thanks to that mechanism, an application can easily
- foresee emissions as accurately as to the millisecond and many days in advance).
-
- Once an event is sent (by the means of MidiSend, MidiSendAt or MidiSendIm functions),
- it is no longer accessible by the application. This event must no longer be refereed
- to, under threat of irremediable disorganisation of the system.
-
- Example of what you must not do :
-
- e = MidiNewEv (typeNote); /* Typical example of fatal error */
- MidiSendIm(myRefNum, e); /* after having being sent, the “e” pointer */
- f = MidiCopyEv(e); /* no longer refers to any valid event */
-
- æKY Event_managing
- æC
-
- The memory management of a standard application is generally achieved by the computer
- "Memory Manager" (MM). The MM deals with dynamic allocation and freeing memory
- blocks of arbitrary length, as well as memory compacting when necessary (excessive
- fragmentation of the memory). Unfortunately, a traditional MM is proved unadapted
- to a real time context. As a matter of fact :
-
- • Only large blocks can be allocated efficiently by traditional MM. For example,
- the Macintosh MM needs 12 more bytes by allocated blocks, which is prohibitive
- for the very small group of bytes represented by a Midi event.
-
- • The allocation time of a block is not constant, but depends on many factors,
- one of which being the fragmentation state of the memory. It can be very long if
- a memory compaction proves necessary. A traditional MM cannot guarantee the response
- time.
-
- • A traditional MM is not re-entrant. No routine under interruption can therefore
- use it directly or indirectly, without irremediably disorganizing the memory
- space.
-
- To overcome these inadaptations, MidiShare holds its own memory manager, adapted
- to the Midi event management and available under interruption. MidiShare drives
- a group of events common to all the applications. Each event has compulsory fields
- (date, channel, port, type, etc...) and variable fields that depend of its type.
-
- The allocation is very easily done by MidiNewEv function which returns an event
- of a suitable type. The disallocation is as easily done by the MidiFreeEv procedure.
- An other way of allocating an event is to duplicate an existing event by the MidiCopyEv
- function. It is possible to know at every moment the available space left by the
- MidiFreeSpace function.
-
- The access to the compulsory fields of the event is directly done ; But the access
- to the variable fields is achieved thru the MidiSetField and MidiGetField functions.
-
-
- Some categories of events do not have a fixed number of fields. Such is the case,
- for example, for the Exclusive System messages. The MidiCountFields function gives
- the number of variable fields of an event. The MidiAddField procedure allows to
- add a field at the tail of an event of variable length.
-
- For some special treatments, it may be useful to have access to the basic functions
- of the memory manager. All the events managed by MidiShare are implemented from
- fixed-sized cells (16 bytes). Most of the events need just one cell. Others like
- the Exclusive Systems use a variable number of cells linked to one another. The
- user application normally does not have to worry about those storage "details".
- Nevertheless, two functions are provided for this low level memory management.
- The first one, MidiNewCell, allows to allocate a simple cell. The second one, MidiFreeCell,
- operates the reverse and de-allocates a cell.
-
- æKY Sequence_managing
- æC
-
- MidiShare offers basic functionalities for the managing of sequences of time
- ordered events. The MidiNewSeq function allocates a new sequence, empty at the
- start. The MidiAddSeq procedure inserts an event into a sequence, maintaining the
- time ordered dates.
-
- The MidiApplySeq procedure is an iterator. It allows to apply a procedure to all
- the events of a sequence. The MidiClearSeq procedure frees the content of one
- sequence and the MidiFreeSeq procedure frees the sequence and its content.
-
- æKY Real_time_tasks
- æC
-
- The alarm concept is the basis of the MidiShare scheduling mechanism. An alarm
- is a procedure whose address is sent to MidiShare by the application. Then, MidiShare
- will call this procedure in real time and often under interruption, to indicate
- the occurrence of an event.
-
- Each application can define two categories of alarms. The first category is defined
- by the MidiSetApplAlarm procedure. It warns of any change in the global context
- of MidiShare (see paragraph "Communications and connections"). The second category
- is defined by the MidiSetRcvAlarm procedure. It warns of the presence of new events
- in the reception fifo. This alarm is always called under interruption. Therefore,
- it must not use either directly or indirectly the Macintosh Memory Manager. On
- the reverse, it can have a free access to all the MidiShare functions (excepted
- MidiOpen and MidiClose), in particular event management. It can also have access
- to global variables of the application, because before the call, MidiShare restores
- its context register.
-
- The Macintosh desk accessories cannot have global variables. To make up for this
- drawback, The MidiSetInfo routine allows each application to define a data area.
- This area remains accessible by MidiGetInfo function, even during the alarm, and
- it also serves as a global context to desk accessories and other purposes.
-
- Once the RcvAlarm set, the application can easily organise its real-time tasks
- thanks to the private event concept. On the reverse of traditional Midi events,
- private events are meant for Midi equipments, but are messages that the application
- sends to itself. The application generally makes use of them to remember a task
- to be done on a precise date.
-
- Therefore, when the date of a private event falls due, MidiShare sets the event
- into the application reception fifo, waiting there to be picked up and handled
- in the same way as Midi events.
-
- MidiShare implements a second mechanism to manage the tasks. This is a time-delayed
- procedure call done thanks to MidiTask (or MidiCall) and MidiDTask procedures.
- To achieve this call, MidiShare collects all the call arguments, as well as the
- routine address to be called and trigs a special event (typeProcess or typeDProcess).
- When a typeProcess event falls in, MidiShare restores the application context and
- does proceed to the call. On the reverse, when a typeDProcess event falls in, it
- is not processed, but set on a waiting list belonging to the application. This
- one will have plenty of time to process the waiting tasks when time comes, owing
- to MidiCountDTasks (giving the number of tasks on wait) and MidiExec1DTask (processing
- the next task on wait) functions.
-
- As the MidiTasks are processed under interruption, they are not allowed to call
- directly or indirectly the operating system. The MidiDTasks allow to by-pass this
- obstacle since the application trigs their processing (generally in the main loop).
-
- Under certain circumstances, "forgetting" a MidiTask or a MidiDTask already
- launched but not yet processed, can be useful. The MidiForgetTask function will
- be used for that purpose. An application MidiDTask waiting list can be deleted
- by MidiFlushDTasks function.
-
- At last, in order to make easier communication between the application tasks and
- to manage accesses, shared between certain variables, two ininterruptible, pointer-handling
- routines can be used. The MidiReadSync function reads and sets to NIL a memory
- address. The MidiWriteSync function updates an address only if NIL.
-
- æKY Synchronisation
- æC
-
- MidiShare can be synchronised to external Midi Time Code (MTC) using the MidiSetSyncMode
- function. MidiSetSyncMode takes one parameter describing the choosed synchronisation
- mode (internal or external) and the synchronisation input port to be used. The
- synchronisation mode is global and all Midi applications are concerned. The function
- MidiGetSyncInfo provides informations about the synchronisation process.
-
- When the synchronisation mode is set to internal (the default mode), MidiShare
- is drived by an internal interrupt every millisecond. The "size" of the MidiShare
- time unit is one millisecond. The function MidiGetTime gives MidiShare internal
- time, the time elapsed since the very first MidiOpen, expressed in millisecond.
-
- When the synchronisation mode is set to external, MidiShare start looking for incomming
- MTC. When enough MTC are detected, MidiShare became locked. It warns all the Midi
- applications, by calling their ApplAlarm, if any, with code MidiSyncStart. A typical
- sequencer may use this information to start playing a sequence according to the
- position of the tape. The function MidiGetExtTime returns the position of the tape
- in milliseconds.
-
- When incomming MTC desappears, MidiShare became unlocked. It automatically adjust
- its time unit to one millisecond and again warns the midi applications via their
- ApplAlarm. with the code MidiSyncStop. A typical sequencer application may decide
- to stop playing its sequences.
-
- While MidiShare is locked, it will maintains a constant offset between its internal
- time and the external time (the time of the tape) by automatically adjusting the
- size of the time unit to follow the speed variations of the incomming MTC. The
- size of the MidiShare time unit will be exactly one millisecond when the MTC runs
- at its nominal speed, it will increase when the MTC slow down and decrease when
- the MTC speed up. For example with a MTC format of 25 frames/second, one frame
- represents 40 milliseconds (1000/25). In this case MidiShare will adjust the size
- of its time unit in order to always have 40 time units per frame whatever the actual
- speed of the incomming MTC is. Consequently, from the point of view of a Midi application,
- the duration of one frame at 25 frames/seconds will always be 40 milliseconds.
-
- The function MidiGetExtTime returns the external time (the time of the tape expressed
- in milliseconds). While MidiShare is locked:
-
- MidiGetTime() - MidiGetExtTime() == constant offset
-
- the difference between the MidiShare internal time and the tape time expressed
- in millisecond is a constant. Two functions are provided to make conversion between
- external and internal time : MidiInt2ExtTime and MidiExt2IntTime. We have:
-
- MidiInt2ExtTime( MidiGetTime() ) == MidiGetExtTime()
-
- MidiExt2IntTime( MidiGetExtTime() ) == MidiGetTime()
-
- Two additional functions, MidiTime2Smpte and MidiSmpte2Time, are provided to make
- conversions between time expressed in millisecond and SMPTE locations. For example:
- MidiTime2Smpte( MidiGetExtTime(), 3, &loc ) set loc with the current smpte location
- of the tape using smpte format 3 (30 frames / seconds).
-
- These functions can be used to convert smpte locations from one format to another.
- For example suppose we want to convert an smpte location from its current format
- to 30 drop frame. we can write: MidiTime2Smpte( MidiSmpte2Time (&loc), 2, &loc);
- where 2 means 30 drop frame.
-
-
-
- æKY Typology
- æC
-
- The listing below presents the different types of MidiShare handled events. This
- typology contains the whole of the standard Midi messages, plus specific messages
- such as the typeNote corresponding to a note with its duration ; The typeStream
- corresponds to a series of arbitrary bytes, possibly including data and status
- codes, sent directly without any processing; or the typePrivate that are application
- private messages.
-
- All these codes may be used in the MidiNewEv function to allocate an event of the
- desirable type and are accessible in an event evType field.
-
- Name Code Comment
- typeNote 0 pitch, vel and duration (16bits)
- typeKeyOn 1 pitch and vel
- typeKeyOff 2 pitch and vel
- typeKeyPress 3 pitch and press
- typeCtrlChange 4 ctrl and val
- typeProgChange 5 prog
- typeChanPress 6 press
- typePitchWheel 7 Lsb et Msb
-
- typeSongPos 8 Lsb et Msb
- typeSongSel 9 song
- typeClock 10 -
- typeStart 11 -
- typeContinue 12 -
- typeStop 13 -
-
- typeTune 14 -
- typeActiveSens 15 -
- typeReset 16 -
-
- typeSysEx 17 data1..dataN
- typeStream 18 byte1..byteN
-
- typePrivate 19..127 arg1, arg2, arg3, arg4
- typeProcess 128 arg1, arg2, arg3, arg4
- typeDProcess 129 arg1, arg2, arg3, arg4
- typeQFrame 130 msg type (0..7) and value
-
- TypeCtrl14b 131
- TypeNonRegParam 132
- TypeRegParam 133
-
- TypeSeqNum 134 extended types from MidiFile 1.0
- TypeText 135
- TypeCopyright 136
- TypeSeqName 137
- TypeInstrName 138
- TypeLyric 139
- TypeMarker 140
- TypeCuePoint 141
- TypeChanPrefix 142
- TypeEndTrack 143
- TypeTempo 144
- TypeSMPTEOffset 145
-
- TypeTimeSign 146
- TypeKeySign 147
- TypeSpecific 148
-
- TypeReserved 149..254
- TypeDead 255 -
-
- æKY Data_structure
- æC
-
- The MidiShare memory management is organised around fixed-sized cells (16 bytes).
- All the events are composed of a header cell that may be followed by one or many
- extension cells. Figure 1 describes the different fields composing the basic cell
- :
-
- The Link field is a multi use link.
- The date field includes the falling in date of the event (from 0 to 231-1).
- The refNum field includes the application reference number sending this.
- The evType field indicates the type of the event.
- The Port field indicates the destination Midi port of the event.
- The Chan field indicates the Midi channel of the event.
-
- These six fields are always present and always have the same meaning, whatever
- the type of the event. Their access can be direct. The info part contains special
- fields the meaning of which depends on the type of the event. In some cases, Info
- contains a pointer to one or several extension cells. Direct access to the special
- fields is possible provided one takes into account the differences of memory storage.
- If not, the special functions MidiGetField and MidiSetField can be used. These
- ones hide the event internal structure and allow to have direct access to the special
- fields by specifying an index between 0 and MidiCountFields - 1.
-
-
- Midi messages with 0, 1 or 2 data bytes, use only one cell, as shown in figure
- 2. These two supplementary fields are accessible by the MidiGetField and MidiSetField
- functions with index 0 and 1.
-
-
- The notes (figure 3) have three more fields at their disposal : 0, 1 and 2 for
- pitch, velocity and duration. The access functions MidiGetField and MidiSetField
- automatically detects the 8, 16 or 32 bit fields.
-
-
- System Exclusive type messages or Stream type messages include variable number
- of fields. They use the structure described on figure 4, build with elementary
- cells linked one to another. The MidiGetField and MidiSetField functions are able
- to follow the links giving access to data. The MidiAddField procedure allows the
- addition of fields at the tail of the message.
- The private or internal type events need the use of an extension cell. This one
- is composed of four 32 bits fields (from 0 to 3) being able to contain any information
- left to the choice of the application.
-
- æKY Error_Codes
- æC
-
- List of the error codes returned by some MidiShare functions.
-
- Name Code Comment
-
- MIDIerrSpace -1 No more space available in the freelist or too many applications
- MIDIerrRefNum -2 Bad reference number
- MIDIerrBadType -3 Bad type of event
- MIDIerrIndex -4 Wrong field index of access to an event
-
- æKY Change_Codes
- æC
-
- List of the change codes sended by MidiShare to ApplAlarm.
- When an application need to know about context modifications like opening and closing
- of applications, opening and closing of midi ports, changes in connections between
- applications, it can install an ApplAlarm (see MidiSetApplAlarm). This ApplAlarm
- is then called by MidiShare every time a context modification happens with a 32-bits
- code describing the modification. The hi 16-bits part of this code is the refNum
- of the application involved in the context modification, the low 16-bits part
- describe the type of change as listed below.
-
- Name Code Mac Code Atari Comment
-
- MIDIOpenAppl 1 - A new application is opened
- MIDICloseAppl 2 - An application is closed
- MIDIChgName 3 - The name of an application is changed
- MIDIChgConnect 4 - A connection is changed
- MIDIOpenModem 5 - The Modem port is opened
- MIDICloseModem 6 - The Modem Port is closed
- MIDIOpenPrinter 7 - The Printer port is opened
- MIDIClosePrinter 8 - The Printer Port is closed
- MIDISyncStart 9 550 Start of synchronization
- MIDISyncStop 10 551 End of synchronization
- MIDIChangeSync 11 552 The synchronization mode is changed
-
- æKY MidiAddField
- æT Function
- æDT MidiAddField( (MidiEvPtr)e, (long)v);
- æC
-
- Description
- Adds a field at the tail of an event of variable length (for example a System Exclusive
- or a Stream) and assigns to it the value transmitted as a parameter.
-
- Prototype
- C Mac ANSI : pascal void MidiAddField (MidiEvPtr e, long v);
- Pascal Mac : procedure MidiAddField (e:MidiEvPtr; v:longint);
-
- Arguments
- e : a MidiEvPtr, it is a pointer to the event to be modified.
- v : a 32-bit integer, it is the value of the field to be added. This value is always
- a long for a purpose of uniformity, but it is internally translate to the right
- size (a byte in this case). The value of v is actually between 0 and 127 for a
- System Exclusive and between 0 and 255 for a Stream.
-
- Example 1 (ANSI C)
- Creates the System Exclusive message "F0 67 18 05 F7"
-
- MidiEvPtr e;
-
- e = MidiNewEv (typeSysEx);
- MidiAddField (e, 0x67L);
- MidiAddField (e, 0x18L);
- MidiAddField (e, 0x05L);
-
- Note : the leading F0 byte and the tailing F7 byte are automatically added by MidiShare
- when the message is transmitted. They must not be added by the user.
-
- Example 2 (ANSI C)
- Creates the Stream message "F8 F0 67 F8 18 05 F7" that mix a System Exclusive and
- two MidiClock (F8)
-
- MidiEvPtr e;
- long i;
-
- e = MidiNewEv(typeStream);
- MidiAddField (e, 0xF8L);
- MidiAddField (e, 0xF0L);
- MidiAddField (e, 0x67L);
- MidiAddField (e, 0xF8L);
- MidiAddField (e, 0x18L);
- MidiAddField (e, 0x05L);
- MidiAddField (e, 0xF7L);
-
- Note : Streams are sent without any transformation (no running status, no check
- of coherence). They can be used for example to send a long system exclusive split
- into several chunks with a little delay between. They can also be used as in the
- example to mix real time messages in a long system exclusive for maintaining synchronization.
-
- Example 3 (ANSI C)
- Create a system exclusive message from an array of values:
-
- char tab[3] = {10, 20, 30};
- MidiEvPtr aSysEx;
-
- MidiEvPtr Array2SysEx( short len, char* vect, short chan, short port )
- {
- MidiEvPtr e;
-
- e = MidiNewEv( typeSysEx ); /* a new, empty sysex */
- Chan(e) = chan; Port(e) = port; /* set destination info */
- while (len—) MidiAddField(e, *vect++); /* append fields */
- return e;
- }
-
- aSysEx = Array2SysEx(3, tab, 0, 0);
-
-
- æKY MidiAddSeq
- æT Function
- æDT MidiAddSeq( (MidiSeqPtr)s, (MidiEvPtr)e);
- æC
-
- Description
- Inserts an event in a sequence while maintaining the dates in time order.
-
- Prototype
- C Mac ANSI : pascal void MidiAddSeq (MidiSeqPtr s, MidiEvPtr e);
- Pascal Mac : procedure MidiAddSeq (s:MidiSeqPtr; e:MidiEvPtr);
-
- Arguments
- s : a MidiSeqPtr, it is a pointer on the sequence to be modified.
- e : a MidiEvPtr, it is a pointer on the event to be added.
-
- Example (ANSI C)
- Creates a sequence of 10 midi clock every 250 ms.
-
- MidiSeqPtr s;
- MidiEvPtr e;
- long d;
-
- s = MidiNewSeq();
- for (d=0; d< 2500; d+=250)
- {
- e = MidiNewEv (typeClock);
- Date(e) = d;
- MidiAddSeq (s, e);
- }
-
- Note : if you are concerned by speed, you must know that sequences are single linked
- lists of time ordered events, so it takes more time for MidiAddSeq to insert an
- event in the middle of a sequence that either at the beginning or at the end.
-
- æKY MidiApplySeq
- æT Function
- æDT MidiApplySeq(MidiSeqPtr s, ApplyProcPtr MyProc);
- æC
-
- Description
- This procedure is an iterator. It allows to apply a procedure to all the events
- of a sequence.
-
- Prototype of MidiApplySeq
- C Mac ANSI : pascal void MidiApplySeq (MidiSeqPtr s, ApplyProcPtr MyProc);
- Pascal Mac : procedure MidiApplySeq (s:MidiSeqPtr; Myproc:ApplyProcPtr
- );
-
- Arguments of MidiApplySeq
- s : a MidiSeqPtr, it is a pointer to the sequence to be browsed;
- MyProc : a ApplyProcPtr is the address of the procedure to apply to each event
- of the sequence.
-
- Prototype of MyProc
- C Mac ANSI : pascal void MyProc (MidiEvPtr e);
- Pascal Mac : procedure MyProc (e:MidiEvPtr);
-
- Argument of MyProc
- e : a MidiEvPtr, it is a pointer to the current event in the sequence.
-
- Example (ANSI C)
- Transpose a sequence by one octave.
-
- MidiSeqPtr s;
-
- void TransposeOctave (MidiEvPtr e)
- {
- if ( EvType(e) == typeNote || EvType(e) == typeKeyOn ||
- EvType(e) == typeKeyOff || EvType(e) == typeKeyPress )
- {
- Pitch(e) += 12; /* normally one must check boundaries */
- }
- }
-
- MidiApplySeq(s, TransposeOctave); /* s is a previously created sequence */
-
- Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
- Therefore, in C, all procedure passed as arguments of a MidiShare function must
- be declared as Pascal. In the previous example, TransposeOctave should be declared
- as : pascal void TransposeOctave (MidiEvPtr e)
-
- æKY MidiAvailEv
- æT Function
- æDT MidiEvPtr myPtr= MidiAvailEv( (short)refnum) ;
- æC
-
- Description
- Gives a pointer to the first event at the head of the reception fifo, without extracting
- it. MidiAvailEv can be used for very special purposes when one wants to test the
- first event in the reception fifo of the application, but without processing it.
-
- Prototype
- C Mac ANSI : pascal MidiEvPtr MidiAvailEv (short refnum) ;
- Pascal Mac : Function MidiAvailEv (refnum: integer) : MidiEvPtr;
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
-
- Result
- The result is a MidiEvPtr, a pointer to the first event in the reception fifo,
- or NIL if the reception fifo is empty.
-
- Example (ANSI C)
- A function that calculate for how long events have been waiting in the reception
- fifo.
-
- long CalculateWaitTime (short refNum)
- {
- MidiEvPtr e;
-
- if (e = MidiAvailEv (refNum))
- return MidiGetTime() - Date(e);
- else
- return 0;
- }
-
- Note : as the event is still in the reception fifo, it must not be destroyed neither
- sent. It can just be tested or duplicated.
-
- æKY MidiCall
- æT Function
- æDT MidiCall(TaskPtr MyProc, long date, short refNum, long a1, long a2, long a3);
- æC
-
- Description
- Defines a time delayed procedure call. When the calling date falls in, the call
- is automatically realized by MidiShare under interruptions. MidiCall is presented
- here for historical reasons, but MidiTask is a better choice.
-
- Prototype of MidiCall
- C Mac ANSI : pascal void MidiCall (TaskPtr MyProc, long date,
- short refNum, long a1, long a2, long a3);
- Pascal Mac : Procedure MidiCall (MyProc:TaskPtr; date:longint; refNum:integer;
- a1,a2,a3: longint);
-
- Arguments of MidiCall
- MyProc : a TaskPtr, it is the address of the procedure to be called.
- date : a 32-bit integer, it is the date at which this call is scheduled.
- refNum : a 16-bit integer, it is the reference number of the application.
- a1,a2,a3 : are 32-bit integers left at the user’s disposal, as arguments of MyProc
-
- Prototype of MyProc
- C Mac ANSI : pascal void MyProc (long date, short refNum,
- long a1, long a2, long a3);
- Pascal Mac : procedure MyProc (date:longint; refNum:integer;
- a1,a2,a3: longint);
-
- Argument of MyProc
- date : a 32-bit integer, it is the date of the call .
- refNum : a 16-bit integer, it is the reference number of the application.
- a1,a2,a3 : are 32-bit integers that can be freely used.
-
- Example (ANSI C )
- Send periodicaly, every 10 ms, a MidiClock during 30 seconds.
-
- void MyClock (long date, short refNum, long delay, long limit, long a3)
- {
- if (date < limit)
- {
- MidiSendIm (refNum, MidiNewEv(typeClock));
- MidiCall (MyClock, date+delay, refNum, delay, limit, a3);
- }
- }
- ...........
- long d;
- ...........
- d = MidiGetTime();
- MyClock (d, myRefNum, 10L, d+30000L, 0L); /* Start now
- the clock for 30s */
-
- Note : This call being done under interruptions, a few precautions should be taken,
- such as not invoking non-reentrant routines of the Operating System (such as the
- Memory Manager on the Macintosh for example). On the contrary, most of the MidiShare
- functions are reentrant, they can be used safely under interrupts.
-
- Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
- Therefore, in C, all procedure passed as arguments of a MidiShare function should
- be declared as Pascal. In the previous example, MyClock should be declared as :
- pascal void MyClock(long date, short refNum, long delay, long limit, long a3);
-
- æKY MidiClearSeq
- æT Function
- æDT MidiClearSeq( (MidiSeqPtr)s);
- æC
-
- Description
- Frees the content of a sequence. MidiClearSeq de-allocates all the events of the
- given sequence. By consequence this sequence becomes empty.
-
- Prototype
- C Mac ANSI : pascal void MidiClearSeq (MidiSeqPtr s);
- Pascal Mac : procedure MidiClearSeq (s:MidiSeqPtr);
-
- Arguments
- s : a MidiSeqPtr, it is a pointer on a sequence whose events are to be freed.
-
- Example (ANSI C)
- Suppress all but the first event of a sequence.
-
- void ClearAllButFirst (MidiSeqPtr s)
- {
- MidiEvPtr e;
-
- if (s && First(s)) /* Check a non empty sequence */
- {
- e = MidiCopyEv(First(s)); /* make a safe copy of the first event */
- MidiClearSeq(s); /* clear the content of the sequence */
- MidiAddSeq(s, e); /* add the event to the empty sequence */
- }
- }
-
- Note : a sequence consist of a header of 4 pointers. The first one points to the
- first event of the sequence. The second one points to the last event. The other
- two pointers are reserved for future extensions and must be NIL. In an empty sequence,
- the pointers to the first and last events are NIL.
-
- æKY MidiClose
- æT Function
- æDT MidiClose( (short)refNum);
- æC
-
- Description
- Closing of a MidiShare application. Every opening of MidiShare with MidiOpen must
- be counter-balanced by a call to MidiClose, so that MidiShare keeps the exact account
- of active applications and released the corresponding internal data structures.
- All the MidiShare applications owning a "context alarm" will be informed of this
- closing.
-
- Prototype
- C Mac ANSI : pascal void MidiClose (short refNum);
- Pascal Mac : procedure MidiClose (refNum:integer);
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application, given
- by the corresponding MidiOpen.
-
- Example (ANSI C)
- A DoNothing MidiShare application.
-
- #include MidiShare.h
- #include <stdio.h>
-
- short myRefNum;
-
- main()
- {
- if ( ! MidiShare() ) exit(1); /* Check MidiShare loaded */
- myRefNum = MidiOpen("Sample"); /* Ask for a reference number */
- if ( myRefNum < 1 ) exit(1); /* Check MidiOpen success */
- printf( "refNum : %i \n", myRefNum); /* Print the reference number
- */ MidiClose(myRefNum); /* And close*/
- }
-
- Note : MidiClose take care of deleting all the connections with the concerned application.
- Therefore if an application sends some Midi events and without delay, does a MidiClose,
- these sent events will probably not be actually transmitted. They just go back
- to the MidiShare Memory Manager.
-
- Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
- Therefore, in C, all strings passed as arguments of a MidiShare function must be
- Pascal strings. In the previous example, one must write : myRefNum = MidiOpen("\pSample");
- æKY MidiConnect
- æT Function
- æDT MidiConnect(short src, short dest, boolean state);
- æC
-
- Description
- Connects or disconnects two applications. The MidiConnect procedure allows to switch
- on or off a connection between a source application and a destination application.
- There is no restrictions to the establishing of connections, an application can
- be source or destination as many times as you wish. Loops are permitted.
-
- Prototype
- C Mac ANSI: pascal void MidiConnect (short src, short dest,
- boolean state);
- Pascal Mac: Procedure MidiConnect (src, dest:integer;
- state:boolean);
- Arguments
- src : a 16-bit integer, it is the reference number of the source application.
- dest : a 16-bit integer, it is the reference number of the destination application.
- state : a boolean, it indicates if a connection must be switched on (True) or off
- (False).
-
- Example (ANSI C)
- Open a MidiShare application and connect it to the physical Midi inputs and outputs.
-
- #include MidiShare.h
- #define PHYSMIDI_IO 0 /* The MidiShare physical Midi I/O ports*/
-
- Main()
- {
- short myRefNum;
-
- myRefNum = MidiOpen("MidiSample");
-
- MidiConnect (PHYSMIDI_IO, myRefNum, TRUE);/* to receive events */
- MidiConnect (myRefNum, 0, TRUE); /* to transmit events */
-
- /* ....... */
-
- MidiClose(myRefNum);
- }
-
- Note : the physical Midi inputs and outputs are represented by the pseudo application
- called "MidiShare" with a reference number of 0 (zero). This pseudo application
- is automatically created when MidiShare wakes up at the very first MidiOpen.
-
- æKY MidiCopyEv
- æT Function
- æDT MidiEvPtr myPtr= MidiCopyEv( (MidiEvPtr)e);
- æC
-
- Description
- Duplicates an event. MidiCopyEv takes into account the structure of the event.
- It can be used to copy every type of events, from simple notes to big system exclusives.
-
- Prototype
- C Mac ANSI : pascal MidiEvPtr MidiCopyEv (MidiEvPtr e);
- Pascal Mac : Function MidiCopyEv (e: MidiEvPtr): MidiEvPtr;
-
- Arguments
- e : a MidiEvPtr, it is a pointer to the event to be copied.
-
- Result
- The result is a MidiEvPtr, a pointer to the copy if the operation was successful.
- The result is NIL if MidiShare was not able to allocate enough memory space for
- the copy.
-
- Example (ANSI C)
- Send from now, 10 times an identical note of pitch 60 every 250 ms.
-
- MidiEvPtr e;
- short myRefNum;
- long d;
- short i;
- ........
-
- e = MidiNewEv (typeNote); /* create template note */
- Pitch(e)= 60; /* fill up its parameters */
- Vel(e) = 80;
- Dur(e) = 250;
- Chan(e) = 0;
- Port(e) = 0;
-
- for (d=MidiGetTime(), i=0; i<10; i++, d+=250) /* send the 10 copies */
- MidiSendAt (myRefNum, MidiCopyEv(e), d); /* of the template */
-
- MidiFreeEv(e); /* and free the template */
-
- Note : it is very important to note that, once an event is sent, it must never
- be used any more by the application. Therefore, if one need to send several times
- the same midi message, one must send different copies.
-
- æKY MidiCountAppls
- æT Function
- æDT short myRet= MidiCountAppls();
- æC
-
- Description
- Gives the number of Midi applications on activity.
-
- Prototype
- C Mac ANSI : pascal short MidiCountAppls();
- Pascal Mac : Function MidiCountAppls : integer;
-
- Result
- The result is a 16-bit integer, the number of currently opened Midi applications.
-
- Example (ANSI C)
- Print the name of all the actives MidiShare applications
-
- void PrintApplNames(void)
- {
- short ref;
- short i;
-
- printf( "List of MidiShare applications :\n" );
- for( i = 1; i <= MidiCountAppls(); ++i )
- {
- ref = MidiGetIndAppl(i);
- printf("%i : %s \n", ref, MidiGetName( ref ) );
- }
- }
-
- Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
- Therefore, in C, the result of MidiGetName is a Pascal string that must be converted
- to a C string before being printed.
-
- æKY MidiCountDTasks
- æT Function
- æDT long myRet= MidiCountDTasks( (short)refNum);
- æC
-
- Description
- Returns the number of time delayed tasks waiting in the list of the application.
- Delayed tasks are function calls that where scheduled with MidiDTask and that are
- now ready to be executed in the DTasksFifo of the application.
-
- Prototype
- C Mac ANSI : pascal long MidiCountDTasks (short refNum);
- Pascal Mac : Function MidiCountDTasks (refNum: integer): longint;
-
- Arguments
-
- refNum : a 16-bit integer, the reference number of the application.
-
- Result
- The result is a 32-bit integer, the number of waiting DTasks.
-
- Example (ANSI C)
- Execute the waiting DTasks of a MidiShare application.
-
- void ExecuteAllDTasks(short refNum)
- {
- long n;
-
- for (n=MidiCountDTasks(refNum), n>0; n—)
- {
- MidiExec1DTask(refNum);
- }
- }
-
- Note : This is what a typical application must do, generally in its main event
- loop, to actually execute previously scheduled MidiDTasks. Since these MidiDTasks
- are executed in the main event loop, they can do Operating System call without
- trouble. In return, as MidiDTasks are not executed under interrupts, they are not
- as accurate in time as MidiTasks.
-
- æKY MidiCountEvs
- æT Function
- æDT long myRet= MidiCountEvs( (short)refnum);
- æC
-
- Description
- Gives the number of events on wait into the reception fifo of the application.
-
- Prototype
- C Mac ANSI : pascal long MidiCountEvs (short refnum);
- Pascal Mac : Function MidiCountEvs (refnum: integer) : longint;
-
- Arguments
- refNum : a 16-bit integer, the reference number of the application.
-
- Result
- The result is a 32-bit integer, the number of waiting events in the reception fifo.
-
- Example (ANSI C)
- A receive alarm that processes all the received events by adding to their date
- a one second delay.
-
- void OneSecDelay (short refNum)
- {
- MidiEvPtr e;
- long n;
-
- for ( n = MidiCountEvs(refNum); n > 0; —n )
- {
- e = MidiGetEv(refNum); /* Get an event from the fifo */
- Date(e) += 1000; /* Add 1000 ms to its date */
- MidiSend(refNum,e); /* Then send the event */
- }
- }
- ......
- MidiSetRcvAlarm(myRefNum,OneSecDelay);/* Activate the receive alarm */
-
- Note : such a procedure can be called repeatedly in the main event loop of the
- application, but for really accurate time control, it must be installed as a receive
- alarm with MidiSetRcvAlarm.
-
- Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
- Therefore, in C, all procedure passed as arguments of a MidiShare function must
- be declared as Pascal. In the previous example, OneSecDelay must be declared as:
- pascal void OneSecDelay (short refNum)
- æKY MidiCountFields
- æT Function
- æDT long myRet= MidiCountFields( (MidiEvPtr)e);
- æC
-
- Description
- Gives the number of fields of an event.
-
- Prototype
- C Mac ANSI : pascal long MidiCountFields (MidiEvPtr e);
- Pascal Mac : Function MidiCountFields (e: MidiEvPtr): longint;
-
- Arguments
- e : a MidiEvPtr, a pointer to the concerned event.
-
- Result
- The result is a 32-bit integer, the number of fields of the event.
-
- Example (ANSI C)
- An universal method for printing of a MidiShare event.
-
- void PrintEv(MidiEvPtr e)
- {
- long i, n;
- n = MidiCountFields(e);
- printf( "Event %x content :\n", e );
- printf( " link : %x\n", Link(e) );
- printf( " date : %i\n", Date(e) );
- printf( " type : %i\n", EvType(e) );
- printf( " ref : %i\n", RefNum(e) );
- printf( " port : %i\n", Port(e) );
- printf( " chan : %i\n", Chan(e) );
- printf( " %i fields : ( ", n );
- for(i=0; i<n; ++i) printf("%i ",MidiGetField(e,i) );
- printf( ")\n" );
- }
-
- Note : MidiShare events carry two kind of information : common information, like
- date, type, channel, port ..., and specific information that depend of the type
- of event. Fields allow a uniform way to access these specific information. Some
- events have fixed number of fields (for example notes have three fields : pitch
- (8-bit), velocity (8-bit) and duration (16-bit)). Some other, like system exclusive
- have a variable number of fields.
-
- æKY MidiDTask
- æT Function
- æDT MidiEvPtr myPtr= MidiDTask( (ProcPtr)MyProc, (long)date, (short)refNum, (long)a1, (long)a2, (long)a3);
- æC
-
-
- Description
- On the same way as MidiTask, MidiDTask allows to realize a time delayed procedure
- call ; but on the reverse to MidiTask, the call is not achieved under interruption
- as soon as falling time is due. The address of the routine to be executed and the
- corresponding arguments will be stored into a special list. The application will
- be allowed to process these on-wait tasks, one by one, thanks to MidiExec1DTask.
-
- Prototype of MidiDTask
- C Mac ANSI : pascal MidiEvPtr MidiDTask (ProcPtr MyProc, long date, short refNum,
- long a1, long a2, long a3);
- Pascal Mac: Function MidiDTask (MyProc:ProcPtr; date:longint; refNum:integer;
- a1,a2,a3: longint):MidiEvPtr;
-
-
- Arguments of MidiDTask
- MyProc : is the address of the procedure to be called.
- date : a 32-bit integer, it is the date at which this call is scheduled.
- refNum : a 16-bit integer, it is the reference number of the application.
- a1,a2,a3 : are 32-bit integers left at the user’s disposal, as arguments to MyProc
-
- Result of MidiDTask
- The result, a MidiEvPtr, is a pointer to a typeDProcess MidiShare event. The result
- is NIL if MidiShare runs out of memory.
-
- Prototype of MyProc
- C Mac ANSI : pascal void MyProc (long date, short refNum,
- long a1, long a2, long a3);
- Pascal Mac : procedure MyProc (date:longint; refNum:integer;
- a1,a2,a3: longint);
-
- Argument of MyProc
- date : a 32-bit integer, it is the date of the call .
- refNum : a 16-bit integer, it is the reference number of the application.
- a1,a2,a3 : are 32-bit integers that can be freely used.
-
-
- Example (ANSI C)
-
- Schedule Action() procedure call 1000 ms ahead.
-
- MidiEvPtr myDTask;
-
- MyDTask = MidiDTask(Action,MidiGetTime()+1000,myRefNum, a1, a2, a3);
-
- Note : The result, in myDTask, can be used to test the success of MidiDTask. It
- can also be used by MidiForgetTask to try to "forget" a scheduled task before it
- happens.
-
- æKY MidiExec1DTask
- æT Function
- æDT MidiExec1DTask( (short)refnum);
- æC
-
- Description
- Processes the first time delayed task on wait in the application list. The time
- delayed tasks scheduled by MidiDTask are not processed as soon as time falls in,
- but stored into a special list proper to each application, so they can be processed
- out of interruption.
-
- Prototype
- C Mac ANSI : pascal void MidiExec1DTask (short refnum);
- Pascal Mac : procedure MidiExec1DTask (refnum: integer);
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
-
- Example (ANSI C)
- Execute the waiting DTasks of a MidiShare application.
-
- void ExecuteAllDTasks(short refNum)
- {
- long n;
-
- for (n=MidiCountDTasks(refNum), n>0; n—)
- {
- MidiExec1DTask(refNum);
- }
- }
-
- Note : This is what a typical application must do, generally in its main event
- loop, to actually execute previously scheduled MidiDTasks. Since these MidiDTasks
- are executed in the main event loop, they can do Operating System Call without
- trouble. In return, as MidiDTasks are not executed under interrupts, they are not
- as accurate in time as MidiTasks.
-
- æKY MidiExt2IntTime
- æT Function
- æDT long myRet= MidiExt2IntTime( (long)time)
- æC
-
- Description
- Convert an external time in millisecond to an internaltime. The convertion is made
- by substractiong the current offset between internal and external time.
-
- Prototypes
- C Mac ANSI : pascal long MidiExt2IntTime (long time)
- Pascal Mac : Function MidiExt2IntTime(time : longint): longint;
-
- Arguments
- time : a 32-bits time in milliseconds
-
- Result
- the corresponding internal time, a 32-bits value in milliseconds.
-
- Note
- When MidiShare is locked we have the following equivalence :
-
- MidiExt2IntTime( MidiGetExtTime() ) == MidiGetTime()
-
- We have also :
-
- TSyncInfo myInfo;
- MidiGetSyncInfo(&myInfo);
- MidiExt2IntTime(x) == x - myInfo.syncOffset
-
-
- æKY MidiFlushDTasks
- æT Function
- æDT MidiFlushDTasks( (short)refnum);
- æC
-
- Description
- Flushes all the waiting DTasks in the application DTask list.
-
- Prototype
- C Mac ANSI : pascal void MidiFlushDTasks (short refnum);
- Pascal Mac : procedure MidiFlushDTasks (refnum: integer);
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
-
- Example (ANSI C)
- Flushes all the waiting DTasks in the application DTask list.
-
- short myRefNum;
-
- .....
-
- MidiFlushDTasks (myRefNum);
-
- æKY MidiFlushEvs
- æT Function
- æDT MidiFlushEvs( (short)refNum );
- æC
-
- Description
- Flushes all the waiting events in the reception fifo of the application.
-
- Prototype
- C Mac ANSI : pascal void MidiFlushEvs( short refNum );
- Pascal Mac : procedure MidiFlushEvs( refNum : integer );
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
-
- Example (ANSI C)
- Flushes all the waiting events in the application reception fifo.
-
- short myRefNum;
-
- .....
-
- MidiFlushEvs (myRefNum);
-
- æKY MidiForgetTask
- æT Function
- æDT MidiForgetTask( (MidiEvPtr *)e);
- æC
-
- Description
- Tries to "forget" a previously scheduled Task or DTasks. This a very powerful,
- but dangerous function. One must be sure that the task is not yet executed before
- calling MidiForgetTask.
-
- Prototype
- C Mac ANSI : pascal void MidiForgetTask (MidiEvPtr *v);
- Pascal Mac : procedure MidiForgetTask (var v: MidiEvPtr);
-
- Arguments
- v : is the address of a variable pointing to a previously scheduled Task or DTask
- but not yet executed. The variable may also contain NIL. In this case MidiForgetTask
- does nothing.
-
- Side effect
- The variable, which address is given in parameter, is set to NIL by MidiForgetTask.
-
- Example 1 (ANSI C)
- Create an infinite periodic clock (every 250ms) and stop it with MidiForgetTask.
-
- MidiEvPtr theClock;
-
- void InfClock (long date, short refNum, long delay, long a2, long a3)
- {
- MidiSendIm (refNum, MidiNewEv(typeClock));
- theClock = MidiTask (InfClock, date+delay, refNum, delay, a2, a3);
- }
-
- InfClock(MidiGetTime(), myRefNum, 250L, 0L, 0L); /* Start the clock*/
- ......... /* Wait some time */
- MidiForgetTask(&theClock); /* And forget it */
-
- Example 2 (ANSI C)
-
- In the previous example theClock always point to a valid task because InfClock
- never stop by itself. If the task may decide to stop itself, it must set the pointer
- to NIL in order to avoid to forget an invalid task.
-
- MidiEvPtr theClock;
-
- void CountClock (long date, short refNum, long delay,long count, long a3)
- {
- if (count > 0)
- {
- MidiSendIm (refNum, MidiNewEv(typeClock));
- theClock = MidiTask (CountClock, date+delay, refNum, delay, count-1, a3);
- } else {
- theClock = NIL; /* here the task decide to stop itself */
- /* so set the pointer to NIL */
- }
- }
-
- CountClock(MidiGetTime(), myRefNum, 250L, 100L, 0L); /* Start 100 clocks
- */ ......... /* Wait some time */
- MidiForgetTask(&theClock); /* And forget it */
-
- If MidiForgetTask happens before the end of the 100 clocks, theClock point to a
- valid task and MidiForgetTask(&theClock) is safe. If MidiForgetTask appens after
- the end of the 100 clocks, theClock contains NIL and MidiForgetTask(&theClock)
- is safe and will do nothing.
-
- æKY MidiFreeCell
- æT Function
- æDT MidiFreeCell( (MidiEvPtr)c);
- æC
-
- Description
- Frees a cell allocated by MidiNewCell function. This is the lowest level for accessing
- the MidiShare Memory Manager. One must be sure to use MidiFreeCell on an individual
- cell allocated with MidiNewCell and not on complete MidiShare events. Not doing
- so may result on losing cells.
-
- Prototype
- C Mac ANSI : pascal void MidiFreeCell (MidiEvPtr c);
- Pascal Mac : procedure MidiFreeCell (c: MidiEvPtr);
-
- Arguments
- c : a MidiEvPtr, a pointer to a basic cell of 16 bytes.
-
- Example (ANSI C)
- Free a cell previously allocated.
-
- MidiEvPtr aCell;
-
- aCell = MidiNewCell();
-
- ....
-
- MidiFreeCell( aCell );
-
- Note : Cells allocated with MidiNewCell must be freed with MidiFreeCell and not
- with MidiFreeEv.
-
- æKY MidiFreeEv
- æT Function
- æDT MidiFreeEv( (MidiEvPtr)e);
- æC
-
- Description
- Frees a MidiShare event allocated with MidiNewEv. MidiFreeEv takes into account
- the event structure by checking the event type. For this reason, MidiFreeEv must
- not be used on cell allocated with MidiNewCell.
-
- Prototype
- C Mac ANSI : pascal void MidiFreeEv (MidiEvPtr e);
- Pascal Mac : procedure MidiFreeEv (e: MidiEvPtr);
-
- Arguments
- e : a MidiEvPtr, it is a pointer to a MidiShare event.
-
- Example (ANSI C)
- A receive alarm that delete all the received events.
-
- short myRefNum;
- .....
-
- void DeleteAll( short refNum )
- {
- MidiEvPtr e;
- long n;
-
- for ( n = MidiCountEvs(refNum); n > 0; —n )
- {
- e = MidiGetEv( refNum ); /* Get an event from the fifo */
- MidiFreeEv( e ); /* Then free it */
- }
- }
- ......
-
- MidiSetRcvAlarm( myRefNum, DeleteAll ); /* Activate the receive alarm */
-
- Note : Obviously it is more simple and fast to use MidiFlushEvs to achieve the
- same result.
-
- Note for Mac users : MidiShare was originally developed for Pascal on the Macintosh.
- Therefore, in C, all procedure passed as arguments of a MidiShare function must
- be declared as Pascal. In the previous example, DeleteAll must be declared as :
- pascal void DeleteAll( short refNum )
- æKY MidiFreeSeq
- æT Function
- æDT MidiFreeSeq( (MidiSeqPtr)s);
- æC
-
- Description
- Frees a sequence and its content. MidiFreeSeq first de-allocates all the events
- of the given sequence and then the sequence header itself.
-
- Prototype
- C Mac ANSI : pascal void MidiFreeSeq (MidiSeqPtr s);
- Pascal Mac : procedure MidiFreeSeq (s:MidiSeqPtr);
-
- Arguments
- s : a MidiSeqPtr, it is a pointer on a sequence to be freed.
-
- Example (ANSI C)
- Frees a previously allocated sequence s.
-
- MidiSeqPtr s;
-
- s = MidiNewSeq();
- ....
- MidiFreeSeq(s);
-
- Note : Once freed, s is no more a valid pointer.
-
- æKY MidiFreeSpace
- æT Function
- æDT long myRet= MidiFreeSpace();
- æC
-
- Description
- Gives the available space. MidiFreeSpace allows to know at any time the number
- of cells remaining available from the MidiShare memory manager.
-
- Prototype
- C Mac ANSI : pascal long MidiFreeSpace(void);
- Pascal Mac : Function MidiFreeSpace : longint;
-
- Arguments
- none
-
- Result
- The result is a 32-bit integer, the number of available free cells in the MidiShare
- memory manager.
-
- Example (ANSI C)
- Print informations about MidiShare memory space.
-
- void PrintMemInfo(void)
- {
- printf("MidiShare memory :\n");
- printf(" free space : %i cells\n", MidiFreeSpace());
- printf(" used space : %i cells\n", MidiTotalSpace() - MidiFreeSpace());
- printf(" total space : %i cells\n", MidiTotalSpace());
- }
-
- Note : MidiFreeSpace inhibits all interrupts during its execution. If the remaining
- space is very large MidiFreeSpace can take a long time to execute and may cause
- overrun errors with fast incoming Midi data.
-
- æKY MidiGetApplAlarm
- æT Function
- æDT ApplAlarmPtr myPtr= MidiGetApplAlarm( (short)refNum);
- æC
-
- Description
- Gives the context alarm of an application. MidiGetAlarm allows to know the address
- of the context alarm procedure associated to the application. This alarm is automatically
- called by MidiShare to inform the application of all the changes happened into
- the active Midi applications (name or connection changes, closing, opening, etc.)
-
- Prototype of MidiGetApplAlarm
- C Mac ANSI : pascal ApplAlarmPtr MidiGetApplAlarm(short refNum);
- Pascal Mac : Function MidiGetApplAlarm(refNum: integer): ApplAlarmPtr;
-
- Arguments of MidiGetApplAlarm
- refNum : a 16-bit integer, it is the reference number of the application.
-
- Result
- the result, a ApplAlarmPtr, is the address of the alarm routine or NIL if no such
- routine where installed.
-
- Prototype of an ApplAlarm routine
- C Mac ANSI : pascal void MyApplAlarm (short refNum, long code);
- Pascal Mac : procedure MyApplAlarm (refNum:integer; code:longint);
-
- Argument of an ApplAlarm routine
- refNum : a 16-bit integer, it is the reference number of the application.
- code : a 32-bit integer, the context modification code.
-
- Example (ANSI C)
- Disable temporarily the application context alarm.
-
- ApplAlarmPtr p;
- .....
- p = MidiGetApplAlarm( myRefNum );
- MidiSetApplAlarm( NIL ); /* Disable application context alarm*/
- .....
- MidiSetApplAlarm( p ); /* Restore application context alarm*/
- æKY MidiGetEv
- æT Function
- æDT MidiEvPtr myPtr= MidiGetEv( (short)refNum) ;
- æC
-
- Description
- Extracts the event on top of the reception fifo. The received events, stored automatically
- by MidiShare in the application reception fifo, can be picked up by successive
- calls to MidiGetEv function.
-
- Prototype
- C Mac ANSI : pascal MidiEvPtr MidiGetEv (short refNum) ;
- Pascal Mac : Function MidiGetEv (refNum: integer) : MidiEvPtr;
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
-
- Result
- a MidiEvPtr, a pointer to the first event in the reception Fifo, or NIL if the
- fifo is empty. The event is extracted form the reception fifo.
-
- Example (ANSI C)
- A receive alarm that processes all the received events by adding to their date
- a one second delay.
-
- void OneSecDelay (short refNum)
- {
- MidiEvPtr e;
- long n;
- for ( n = MidiCountEvs(refNum); n > 0; —n )
- {
- e = MidiGetEv(refNum); /* Get an event from the fifo */
- Date(e) += 1000; /* Add 1000 ms to its date */
- MidiSend(refNum,e); /* Then send the event */
- }
- }
- .....
-
- MidiSetRcvAlarm(myRefNum,OneSecDelay);/* Activate the receive alarm */
-
- Note : such a procedure can be called repeatedly in the main event loop of the
- application, but for really accurate time control, it must be installed as a receive
- alarm with MidiSetRcvAlarm. Note for Mac users : MidiShare was originally developed
- for Pascal on the Macintosh. Therefore, in C, all procedure passed as arguments
- of a MidiShare function must be declared as Pascal. In the previous example, OneSecDelay
- must be declared as: pascal void OneSecDelay (short refNum)
-
- æKY MidiGetExtTime
- æT Function
- æDT long myRet= MidiGetExtTime();
- æC
-
- Description
- Gives the current external time, the position of the tape converted in milliseconds.
-
- Prototypes
- C Mac ANSI : pascal long MidiGetExtTime (void);
- Pascal Mac : FUNCTION MidiGetExtTime : longint;
-
- Arguments
- none
-
- Example (ANSI C)
- Gives the SMPTE current location of the tape.
-
- TSyncInfo myInfo;
- TSmpteLocation myLoc;
-
- MidiGetSyncInfo(&myInfo);
- MidiTime2Smpte( MidiGetExtTime(), myInfo.syncFormat, &myLoc);
-
- Note
- When the tape is stopped, MidiGetExtTime returns the stop position of the tape
- converted in milliseconds.
-
- æKY MidiGetField
- æT Function
- æDT long myRet= MidiGetField( (MidiEvPtr)e, (long)f);
- æC
-
- Description
- Gives the i index field value of an event. Field index start from 0. Depending
- of the event type and field nature, the field format can be 8, 16 or 32-bit. MidiGetField
- deals with all the format conversion and the result is always a 32-bit integer.
-
- Prototype
- C Mac ANSI : pascal long MidiGetField (MidiEvPtr e, long f);
- Pascal Mac : Function MidiGetField (e: MidiEvPtr; f: longint): longint;
-
- Arguments
- e : a MidiEvPtr, it is a pointer on the event to be acces.
- f : a 32-bit integer, it is the field number to be read (numbered from 0).
-
- Result
- The result is a 32-bit integer, the value of the field. Fields are considered as
- unsigned.
-
- Example (ANSI C)
- An universal method for printing of a MidiShare event.
-
- void PrintEv(MidiEvPtr e)
- {
- long i, n;
-
- n = MidiCountFields(e);
- printf( "Event %x content :\n", e );
- printf( " link : %x\n", Link(e) );
- printf( " date : %i\n", Date(e) );
- printf( " type : %i\n", EvType(e) );
- printf( " ref : %i\n", RefNum(e) );
- printf( " port : %i\n", Port(e) );
- printf( " chan : %i\n", Chan(e) );
- printf( " %i fields : ( ", n );
- for(i=0; i<n; ++i) printf("%i ",MidiGetField(e,i) );
- printf( ")\n" );
- }
-
- Note : MidiShare events carry two kind of information : common information, like
- date, type, channel, port ..., and specific information that depend of the type
- of event. Fields allow a uniform way to acces these specific information. Some
- events have fixed number of fields (for example notes have three fields : pitch
- (8-bit), velocity (8-bit) and duration (16-bit)). Some other, like system exclusive
- have a variable number of fields.
-
- æKY MidiGetFilter
- æT Function
- æDT FilterPtr myPtr= MidiGetFilter( (short)refNum);
- æC
-
- Description
- Gives the associated filter of an application. Each application can select the
- events to be received by using a filter. The filtering processus is local to the
- application and has no influence on the events received by other applications.
-
-
- Prototype
- C Mac ANSI : pascal FilterPtr MidiGetFilter (short refNum);
- Pascal Mac : Function MidiGetFilter (refNum: integer): FilterPtr;
-
- Arguments
- refNum : a 16-bit integer, the reference number of the application
-
- Result
- the result is a FilterPtr, a pointer to the filter associated to the application,
- or NIL if there is no such filter (in this case the application accepts any events)
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY MidiGetIndAppl
- æT Function
- æDT short myRet= MidiGetIndAppl( (short)index);
- æC
-
- Description
- Gives the reference of number of an application from is order number. The MidiGetIndAppl
- function allows to know the reference number of any application by giving its order
- number (a number between 1 and MidiCountAppls() ).
-
- Prototype
- C Mac ANSI : pascal short MidiGetIndAppl (short index);
- Pascal Mac : Function MidiGetIndAppl (index: integer) : integer;
-
- Arguments
- index : a 16-bit integer, it is the index number of an application between 1 and
- MidiCountAppls().
-
- Result
- The result is an application reference number or MIDIerrIndex if the index is out
- of range.
-
- Example (ANSI C)
-
- Print the name of all the actives MidiShare applications
-
- void PrintApplNames(void)
- {
- short ref;
- short i;
-
- printf( "List of MidiShare applications :\n" );
- for( i = 1; i <= MidiCountAppls(); ++i )
- {
- ref = MidiGetIndAppl(i);
- printf("%i : %s \n", ref, MidiGetName( ref ) );
- }
- }
-
- Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
- Consequently, in C, the result of MidiGetName is a Pascal string that must be converted
- to a C string before being printed.
-
- æKY MidiGetInfo
- æT Function
- æDT void* myPtr= MidiGetInfo( (short)refNum );
- æC
-
- Description
- Gives the content of a 32-bit field an application can use for any purpose. This
- field remains accessible by MidiGetInfo during alarms and interrupts. It can be
- used as a global context if necessary (for example for desk accessories on the
- Macintosh).
-
- Prototype
- C Mac ANSI : pascal void* MidiGetInfo( short refNum );
- Pascal Mac : Function MidiGetInfo( refNum: integer ) : Ptr;
-
- Arguments
- refNum : a 16-bit integer, the reference number of the application
-
- Result
- The result is a 32-bit integer, the last value set by MidiSetInfo
-
- Example (ANSI C)
- << to be supplied >>
-
-
- æKY MidiGetName
- æT Function
- æDT MidiName name= MidiGetName( (short)refNum);
- æC
-
- Description
- Gives the name of an application. Knowing an application reference number, it is
- possible to find its name using the MidiGetName function. On the reverse, it is
- also possible to find the reference number of an application via its name using
- the MidiGetNamedAppl function.
-
- Prototype
- C Mac ANSI : pascal MidiName MidiGetName(short refNum);
- Pascal Mac : Function MidiGetName (refNum: integer) : MidiName;
-
- Arguments
- refNum : a 16-bit integer, the reference number of the application
-
- Result
- The result is pointer on a character string representing the application name.
-
- Example (ANSI C)
- Print the name of all the active MidiShare applications
-
- void PrintApplNames(void)
- {
- short ref;
- short i;
-
- printf( "List of MidiShare applications :\n" );
- for( i = 1; i <= MidiCountAppls(); ++i )
- {
- ref = MidiGetIndAppl(i);
- printf("%i : %s \n", ref, MidiGetName( ref ) );
- }
- }
-
- Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
- Consequently, in C, the result of MidiGetName is a Pascal string that must be converted
- to a C string before being printed.
-
- æKY MidiGetNamedAppl
- æT Function
- æDT short myRet= MidiGetNamedAppl( (MidiName)name);
- æC
-
- Description
- Gives the reference number of an application. Knowing an application name, it is
- possible to find its reference number using the MidiGetNamedAppl function. On the
- reverse, it is also possible to find the name of an application via its reference
- number using the MidiGetName function.
-
- Prototype
- C Mac ANSI pascal short MidiGetNamedAppl (MidiName name);
- Pascal Mac : Function MidiGetNamedAppl (name: MidiName) : integer;
-
- Arguments
- name : the application name.
-
- Result
- The result is the reference number of the application.
-
- Example (ANSI C)
- Find the reference number of the "MidiShare" pseudo-application.
-
- short r;
-
- r = MidiGetNamedAppl("MidiShare");/* MidiShare reference is always 0 */
-
- Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
- Consequently, in C, all strings passed as arguments of a MidiShare function must
- be Pascal strings. In the previous example, one must write : MidiGetNamedAppl("\pMidiShare")
-
- æKY MidiGetPortState
- æT Function
- æDT Boolean myRet= MidiGetPortState( (short)port);
- æC
-
- Description
- Gives the Midi port state. The switching on or off of Midi ports is controlled
- by the MidiSetPortState and MidiGetPortState routines. These must be used with
- care since they affect all the applications.
-
- Prototype
- C Mac ANSI : pascal Boolean MidiGetPortState(short port);
- Pascal Mac : Function MidiGetPortState(port: integer): boolean;
-
- Arguments
- port : a port number from 0 to 255.
-
- Result
- The result is true if the port is open or false if the port is closed.
-
- Example (ANSI C)
- Print the state of all the Midi ports.
-
- void PrintPortsState(void)
- {
- short i;
-
- printf( "Midi ports state :\n");
- for( i = 0; i < 256; ++i )
- {
- if ( MidiGetPortState( i ) )
- printf(" %i is open \n", i );
- else
- printf(" %i is closed \n", i );
- }
- }
-
- Note : On the Atari, there is just one Midi port (port 0), and on the Macintosh
- there are just two ports (port modem: 0, port printer: 1). But the future Lan version
- of MidiShare will allow up to 256 ports to be used. Therefore, applications must
- consider that 256 ports are available.
-
- æKY MidiGetRcvAlarm
- æT Function
- æDT RcvAlarmPtr myPtr= MidiGetRcvAlarm( (short)refNum);
- æC
-
- Description
- Gives the address of reception alarm of an application.The reception alarm warns
- of the presence of new events in the reception fifo. This alarm is always called
- under interruption. Therefore, it must not make use, either directly or indirectly,
- the Macintosh Memory Manager. On the reverse, it can have a free access to all
- the MidiShare functions (exept MidiOpen and MidiClose), in particular event management.
- It can also use global variables of the application, because, before the call,
- MidiShare restaures the global context register of the application.
-
- Prototype
- C Mac ANSI : pascal RcvAlarmPtr MidiGetRcvAlarm(short refNum);
- Pascal Mac : function MidiGetRcvAlarm(refNum: integer):RcvAlarmPtr;
-
- Arguments
- refNum : a 16-bit integer, the reference number of the application
-
- Result
- The result, a RcvAlarmPtr, it is the address of the receive alarm routine or NIL
- if no such routine where installed.
-
- Prototype of a RcvAlarm routine
- C Mac ANSI : pascal void MyRcvAlarm (short refNum);
- Pascal Mac : procedure MyRcvAlarm (refNum:integer);
-
- Argument of a RcvAlarm routine
- refNum : a 16-bit integer, it is the reference number of the application.
-
- Example (ANSI C)
- Temporarily disable the application receive alarm.
-
- RcvAlarmPtr p;
- .....
- p = MidiGetRcvAlarm( myRefNum );
- MidiSetRcvAlarm( NIL ); /* Disable application receive alarm */
- .....
- MidiSetRcvAlarm( p ); /* Restaure application receive alarm */
-
- æKY MidiGetSyncInfo
- æT Function
- æDT MidiGetSyncInfo( (SyncInfoPtr)p);
- æC
-
- Description
- Fills a TSyncInfo record with informations about the current state of the MTC synchronisation.
-
- Prototypes
- C Mac ANSI : pascal void MidiGetSyncInfo (SyncInfoPtr p);
- Pascal Mac : PROCEDURE MidiGetSyncInfo (p: SyncInfoPtr);
-
- Arguments
- p: a SyncInfoPtr, a pointer to a TSyncInfo record
-
- description of a TSyncInfo record
- typedef struct TSyncInfo
- {
- long time; // the current MidiShare date (in milliseconds)
- long reenter; // the current reentrancy count of the interrupt handler
- unsigned short syncMode; // the current synchronisation mode as defined
- by MidiSetSyncMode
- Byte syncLocked; // the current synchronisation state
- (0 : unlocked 1 : locked)
- Byte syncPort; // the current synchronisation port
- long syncStart; // the date MidiShare started beeing locked
- to external sync (in ms)
- long syncStop; // the date MidiShare stopped being locked
- to external sync (in ms)
- long syncOffset; // the current offset (MidiGetExtTime() - MidiGetTime(), in ms)
- long syncSpeed; // the current value for the timer (implementation
- dependent)
- long syncBreaks; // the current count of breaks (transition from state
- locked to unlocked)
- short syncFormat; // the current synchronisation format
- (0 : 24 f/s, 1 : 25 f/s, 2 : 30DF f/s, 3 : 30 f/s)
- } TSyncInfo;
-
- Note 1
- syncMode is an unsigned 16-bits word of struture : xa000000pppppppp.
- x (bit 15) is used to choose between internal synchronisation (x=0) and external
- synchronisation (x=1) a (bit 14) is used to choose between synchronisation on port
- p (a=0) and synchronisation on any port (a=1) bit 13:8 are reserved for future
- use and must be set to 0. p (bit 0:7) is the synchronisation port to be used when
- x=1 and a=0. When a=1 the port number is ignored, the first port with incomming
- MTC is used.
-
- Note 2
- While MidiShare is locked (syncLocked == 1) syncOffset is constant and we have
- the following relationships : MidiGetExtTime() == MidiGetTime() + syncOffset
- MidiInt2ExtTime(x) == x + syncOffset
- MidiExt2IntTime(x) == x - syncOffset
-
- Example (ANSI C)
- Gives the SMPTE start location of the tape.
-
- TSyncInfo myInfo;
- TSmpteLocation myLoc;
- MidiGetSyncInfo(&myInfo);
- MidiTime2Smpte( MidiInt2ExtTime(myInfo.syncStart), myInfo.syncFormat, &myLoc);
-
- æKY MidiGetTime
- æT Function
- æDT long myRet= MidiGetTime();
- æC
-
- Description
- Gives in milliseconds the time past since the starting up of MidiShare.
-
- Prototype
- C Mac ANSI : pascal long MidiGetTime();
- Pascal Mac : Function MidiGetTime : longint;
-
- Arguments
- none
-
- Result
- The result is a 32-bit integer, the elapsed time in milliseconds since the starting
- up of MidiShare.
-
- Example (ANSI C)
- A wait function :
-
- void wait(long delay)
- {
- long d;
-
- d = MidiGetTime() + delay;
- while (MidiGetTime() < d);
- }
-
- æKY MidiGetVersion
- æT Function
- æDT short myRet= MidiGetVersion();
- æC
-
- Description
- Gives the version number of MidiShare
-
- Prototype
- C Mac ANSI : pascal short MidiGetVersion(void);
- Pascal Mac : Function MidiGetVersion : integer;
-
- Arguments
- none
-
- Result
- The result is a 16-bit integer, the MidiShare version number. A result of 161 means
- <version 1.61>.
-
- Example (ANSI C)
- Print the MidiShare version number
-
- void PrintVersion(void)
- {
- printf( "MidiShare version : %4.2f\n", MidiGetVersion()/100.0);
- }
-
- æKY MidiGrowSpace
- æT Function
- æDT long myRet= MidiGrowSpace( (long)n);
- æC
-
- Description
- Try to increase the memory space of MidiShare.
-
- Prototype
- C Mac ANSI : pascal long MidiGrowSpace(long n);
- Pascal Mac : Function MidiGrowSpace(n : longint): longint;
-
- Arguments
- n : the number of cells to increase the MidiShare memory space.
-
- Result
- The result is a 32-bit integer, the number of new cells actually allocated.
-
- Example (ANSI C)
- Add 1000 cells to MidiShare memory space.
-
- void TryGrowSpace(void)
- {
- printf( "Try to allocate 1000 cells : %ld\n", MidiGrowSpace(1000));
- }
-
-
- æKY MidiInt2ExtTime
- æT Function
- æDT long myRet= MidiInt2ExtTime( (long)time)
- æC
-
- Description
- Convert an internal time in millisecond to an external time. The convertion is
- made by adding the current offset between internal and external time.
-
- Prototypes
- C Mac ANSI : pascal long MidiInt2ExtTime (long time)
- Pascal Mac : FUNCTION MidiGetExtTime (time : longint) : longint;
-
- Arguments
- time : a 32-bits time in milliseconds
-
- Result
- the corresponding external time, a 32-bits value in milliseconds.
-
- Note
- When MidiShare is locked we have the following equivalence :
-
- MidiInt2ExtTime( MidiGetTime() ) == MidiGetExtTime()
-
- We have also :
-
- TSyncInfo myInfo;
- MidiGetSyncInfo(&myInfo);
- MidiInt2ExtTime(x) == x + myInfo.syncOffset
-
- æKY MidiIsConnected
- æT Function
- æDT Boolean myRet= MidiIsConnected( (short)src, (short)dest );
- æC
-
- Description
- Gives the state of a connection between two MidiShare applications. Connections
- allow real-time communications of midi events between applications.
-
- Prototype
- C Mac ANSI : pascal Boolean MidiIsConnected( short src, short dest );
- Pascal Mac : Function MidiIsConnected( src, dest: integer) : boolean;
-
- Arguments
- src : is the reference number of a source application
- dest : is the reference number of a destination application
-
- Result
- The result is true when a connection exist between the source and the destination,
- and false otherwise.
-
- Example (ANSI C)
- Print all the sources of an application
-
- void PrintSources(short refNum)
- {
- short src;
- short i;
-
- printf( "Sources of : %s\n", MidiGetName( refNum) );
- for( i = 1; i <= MidiCountAppls(); ++i )
- {
- src = MidiGetIndAppl(i);
- if ( MidiIsConnected(src, refNum) )
- printf(" %i : %s \n", src, MidiGetName( src ) );
- }
- }
-
- Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
- Consequently, the result of MidiGetName is a Pascal string that must be converted
- to a C string to be printed.
-
- æKY MidiNewCell
- æT Function
- æDT MidiEvPtr myPtr= MidiNewCell();
- æC
-
- Description
- Allocates a simple memory cell from the MidiShare memory manager. For some special
- treatments, it may be useful to have access to the basic functions of the memory
- manager. All the events managed by MidiShare are implemented from fixed-sized cells
- (16 bytes).
-
- Prototype
- C Mac ANSI : pascal MidiEvPtr MidiNewCell(void);
- Pascal Mac : Function MidiNewCell : MidiEvPtr;
-
- Arguments
- none
-
- Result
- The result a MidiEvPtr, a pointer to a memory cell, or NIL when memory space is
- exhausted.
-
- Example (ANSI C)
- Allocate a new cell.
-
- MidiEvPtr c;
-
- c = MidiNewCell();
-
- .....
-
- MidiFreeCell(c);
-
- Note : Cells allocated with MidiNewCell must be freed with MidiFreeCell and not
- with MidiFreeEv.
-
- æKY MidiNewEv
- æT Function
- æDT MidiEvPtr myPtr= MidiNewEv( (short)typeNum );
- æC
-
- Description
- Allocates a new event of desirable type.
-
- Prototype
- C Mac ANSI : pascal MidiEvPtr MidiNewEv( short typeNum );
- Pascal Mac : Function MidiNewEv(typeNum: integer): MidiEvPtr;
-
- Arguments
- typeNum : the type of event to be allocated
-
- Result
- The result a MidiEvPtr, a pointer to a MidiShare event of the desired type, or
- NIL if the MidiShare memory space is exhausted.
-
- Example (ANSI C)
- A function for creating note events.
-
-
- MidiEvPtr Note(long date, short pitch, short vel,
- long dur, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e=MidiNewEv(typeNote) )
- {
- Date(e) = date; Pitch(e) = pitch; Vel(e) = vel;
- Dur(e) = dur; Chan(e) = chan; Port(e) = port;
- }
- return e;
- }
-
- æKY MidiNewSeq
- æT Function
- æDT MidiSeqPtr myPtr= MidiNewSeq();
- æC
-
- Description
- Allocation of a new empty sequence.
-
- Prototype
- C Mac ANSI : pascal MidiSeqPtr MidiNewSeq();
- Pascal Mac : Function MidiNewSeq : MidiSeqPtr;
-
- Arguments
- none
-
- Result
- The result is a MidiSeqPtr, a pointer to an empty sequence.
-
-
- Example (ANSI C)
- Create a sequence of 10 Midi clocks.
-
- MidiSeqPtr ClockSeq()
- {
- MidiSeqPtr s;
- MidiEvPtr e;
- long d;
-
- s = MidiNewSeq();
- for (d=0; d< 2500; d+=250)
- {
- e = MidiNewEv (typeClock);
- Date(e) = d;
- MidiAddSeq (s, e);
- }
- return s;
- }
-
- æKY MidiOpen
- æT Function
- æDT short myRet= MidiOpen( (MidiName)applName );
- æC
-
- Description
- Opening of MidiShare. MidiOpen allows the recording of some information relative
- to the application context (its name, the value of the global data register, etc...),
- to allocate a reception FIFO and to attribute a unique reference number to the
- application. In counterpart to any MidiOpen call, the application must call the
- MidiClose function before leaving, by giving its reference number as an argument.
- MidiShare can thus be aware of the precise number of active Midi applications.
-
-
- Prototype
- C Mac ANSI : pascal short MidiOpen( MidiName applName );
- Pascal Mac : Function MidiOpen( applName: midiName ): integer;
-
- Arguments
- applName : the name of the application.
-
- Result
- The result is a unique reference number identifing the application.
-
- Example (ANSI C)
- A DoNothing MidiShare application.
-
- #include MidiShare.h
- #include <stdio.h>
-
- short myRefNum;
-
- main()
- {
- if ( ! MidiShare() ) exit(1); /* Check MidiShare loaded */
- myRefNum = MidiOpen("Sample"); /* Ask for a reference number */
- if ( myRefNum < 1 ) exit(1); /* Check MidiOpen success */
- printf( "refNum : %i \n", myRefNum);/* Print the reference number*/
- MidiClose(myRefNum); /* And close */
- }
-
- Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
- Consequently, in C, all strings passed as arguments of a MidiShare function must
- be Pascal strings. In the previous exemple, one must write : myRefNum = MidiOpen("\pSample");
-
- æKY MidiReadSync
- æT Function
- æDT void* myPtr= MidiReadSync( (void* )adrMem) ;
- æC
-
- Description
- The MidiReadSync function reads and sets to NIL a memory address. This function
- is none-interruptible in order to make easier communication between the application
- tasks that run at interrupt level. It can be used to implement some sort of "mail
- boxes" in conjunction of MidiWriteSync.
-
- Prototype
- C Mac ANSI : pascal void* MidiReadSync( void* adrMem) ;
- Pascal Mac : Function MidiReadSync( adrMem: univ ptr): ptr;
-
- Arguments
- adrMem : the address of a variable containing a 32-bit data.
-
- Result
- The result is the content of the variable.
-
- Side effect
- Once read, the content of the variable is set to NIL.
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY MidiSend
- æT Function
- æDT MidiSend( (short)refNum, (MidiEvPtr)e );
- æC
-
- Description
- Sends an event. A copy of the event is sended to all the application destinations.
- The date field of the event is used to specify when destinations will actually
- receive the event.
-
- Prototype
- C Mac ANSI : pascal void MidiSend( short refNum, MidiEvPtr e );
- Pascal Mac : procedure MidiSend( refNum: integer; e : MidiEvPtr);
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
- e : a MidiEvePtr, it is a pointer to the event to send.
-
- Example (ANSI C)
- A receive alarm that processes all the received events by adding a one second delay
- to their date.
-
- void OneSecDelay (short refNum)
- {
- MidiEvPtr e;
- long n;
-
- for ( n = MidiCountEvs(refNum); n > 0; —n )
- {
- e = MidiGetEv(refNum); /* Get an event from the fifo */
- Date(e) += 1000; /* Add 1000 ms to its date */
- MidiSend(refNum,e); /* Then send the event */
- }
- }
- ......
- MidiSetRcvAlarm(myRefNum,OneSecDelay); /* Activate the receive alarm*/
-
- Note : such a procedure can be called repeatedly in the main event loop of the
- application, but for really accurate time control, it must be installed as a receive
- alarm with MidiSetRcvAlarm.
-
- Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
- Consequently, in C, all procedure passed as arguments of a MidiShare function must
- be declared as Pascal. In the previous exemple, OneSecDelay must be declared as
- : pascal void OneSecDelay (short refNum)
-
- æKY MidiSendAt
- æT Function
- æDT MidiSendAt( (short)refNum, (MidiEvPtr)e, (long)d );
- æC
-
- Description
- Sends an event. A copy of the event is sended to all the application destinations.
- The date argument is used to specify when destinations will actually receive the
- event.
-
- Prototype
- C Mac ANSI : pascal void MidiSendAt( short refNum, MidiEvPtr e, long d );
- Pascal Mac : procedure MidiSendAt( refNum:integer; e:MidiEvPtr; d:longint);
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
- e : a MidiEvePtr, it is a pointer to the event to send.
- d : a 32-bit integer, the date when destinations will receive the event.
-
- Example (ANSI C)
- Equivalence between MidiSend, MidiSendAt and MidiSendIm :
-
- MidiSendAt(myRefNum,e,MidiGetTime());
-
- is equivalent to :
-
- MidiSendIm(myRefNum,e);
-
- is equivalent to :
-
- Date(e) = MidiGetTime();
- MidiSend( myRefNum, e );
-
- æKY MidiSendIm
- æT Function
- æDT MidiSendIm( (short)refNum, (MidiEvPtr)e );
- æC
-
- Description
- Immediatly sends an event. A copy of the event is sended to all the application
- destinations.
-
- Prototype
- C Mac ANSI : pascal void MidiSendIm( short refNum, MidiEvPtr e );
- Pascal Mac : procedure MidiSendIm( refNum:integer; e:MidiEvPtr );
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
- e : a MidiEvePtr, it is a pointer to the event to send.
-
- Example (ANSI C)
- equivalence between MidiSend, MidiSendAt and MidiSendIm :
-
- MidiSendIm(myRefNum,e);
-
- is equivalent to :
-
- MidiSendAt(myRefNum,e,MidiGetTime());
-
- is equivalent to :
-
- Date(e) = MidiGetTime();
- MidiSend( myRefNum, e );
-
- æKY MidiSetApplAlarm
- æT Function
- æDT MidiSetApplAlarm(short refNum, ApplAlarmPtr
- æC
-
- Description
- Defines the context alarm of an application. These alarm will be called by MidiShare
- on every application global context modifications (opening and closing of applications,
- opening and closing of midi ports, changes in connections between applications,
- SMPTE synchronisation).
-
- Prototype
- alarm);
- C Mac ANSI : pascal void MidiSetApplAlarm(short refNum, ApplAlarmPtr
- alarm);
- Pascal Mac : Procedure MidiSetApplAlarm(refNum:integer;
- alarm:ApplAlarmPtr);
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
- alarm: a ApplAlarmPtr, a pointer to the application context alarm routine.
-
- Prototype of a ApplAlarm routine
- C Mac ANSI : pascal void MyApplAlarm (short refNum, long code);
- Pascal Mac : procedure MyApplAlarm (refNum:integer; code:longint);
-
- Argument of a ApplAlarm routine
- refNum : a 16-bit integer, it is the reference number of the application.
- code : a 32-bit integer, the context modification code : 0xRRRRMMMM where RRRR
- is the Reference number of the involved application and MMMM the type of change
- (see Midi Change Codes).
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY MidiSetField
- æT Function
- æDT MidiSetField( (MidiEvPtr)e, (long)f, (long)v );
- æC
-
- Description
- Attributes a value to the i index data field of an event. The access to the compulsory
- fields of the event is directly done. But the access to the variables fields is
- achieved thru the MidiSetField and MidiGetField functions. The procedure deals
- with the conversion of this value into the concerned field format (8, 16 or 32-bit).
-
- Prototype
- C Mac ANSI : pascal void MidiSetField( MidiEvPtr e, long f, long v );
- Pascal Mac : procedure MidiSetField( e:MidiEvPtr; f:longint;
- v:longint );
-
- Arguments
- e : a MidiEvPtr, a pointer to the event to modifie
- f : a 32-bit integer, the index number of the field to modify
- ( from 0 to MidiCountFields(e)-1)
- v : a 32-bit value to put in the field. This value will be converted to the
- right size (8, 16 or 32-bit)
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY MidiSetFilter
- æT Function
- æDT MidiSetFilter( (short)refNum, (FilterPtr)filter );
- æC
-
- Description
- Associates a filter to an application. Each application can select the events to
- be received by using a filter. The filtering process is local to the application
- and has no influence on the events received by the other applications. The implementation
- of these filters is achieved by two routines : MidiSetFilter and MidiGetFilter.
-
- Prototype
- C Mac ANSI : pascal void MidiSetFilter( short refNum, FilterPtr filter );
- Pascal Mac : procedure MidiSetFilter( refNum: integer; filter: FilterPtr );
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
- filter : a FilterPtr, a pointer to the application filter.
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY MidiSetInfo
- æT Function
- æDT MidiSetInfo( short refNum, void* infoZone );
- æC
-
- Description
- Defines the global information area of an application. The Macintosh desk accessories
- cannot have global variables. To make up for this drawback, the MidiSetInfo routine
- allows each application to define a data area. This area remains accessible by
- MidiGetInfo function, even during the alarm, and also serves as a global context
- to desk accessories.
-
- Prototype
- C Mac ANSI : pascal void MidiSetInfo( short refNum, void* infoZone );
- Pascal Mac : procedure MidiSetInfo( refNum: integer; infoZone: Ptr );
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
- infoZone : an arbitrary 32-bit value, generaly a pointer or a handle.
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY MidiSetName
- æT Function
- æDT MidiSetName( (short)refNum, (MidiName)name );
- æC
-
- Description
- Changes the name of an application.
-
- Prototype
- C Mac ANSI : pascal void MidiSetName( short refNum, MidiName name );
- Pascal Mac : procedure MidiSetName( refNum: integer; name: midiName);
-
- Arguments
- refNum : a 16-bit integer, it is the reference number of the application.
- name : a MidiName, the new application name.
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY MidiSetPortState
- æT Function
- æDT MidiSetPortState( (short)port, (Boolean)state );
- æC
-
- Description
- Opening and closing of a Midi port. The implementation of Midi ports is controlled
- by the MidiSetPortState and MidiGetPortState routines. These must be used with
- care since they affect all the applications. A closed port is available for other
- uses (printing, AppleTalk, etc...). The Midi applications holding a "context alarm"
- will be informed of this change in the ports state.
-
- Prototype
- C Mac ANSI : pascal void MidiSetPortState( short port, Boolean state );
- Pascal Mac : procedure MidiSetPortState( port: integer;
- state: boolean );
-
- Arguments
- port : a 16-bit integer, the port number to control.
- state : a Boolean, True : to open a port, False : to close a port.
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY MidiSetRcvAlarm
- æT Function
- æDT MidiSetRcvAlarm( short refNum, RcvAlarmPtr alarm );
- æC
-
- Description
- Defines the event reception alarm of an application. The alarm will be automatically
- called by MidiShare to inform the application of the presence of new events in
- its reception fifo. This alarm is always called under interruption. It must not
- use, directly or indirectly, the Macintosh Memory Manager. It can freely access
- to all the others MidiShare functions, particularly to the event management (but
- not MidiOpen and MidiClose). It can also use application global variables, since
- MidiShare restaures its global context register, before the call.
-
- Prototype of MidiSetRcvAlarm
- C Mac ANSI : pascal void MidiSetRcvAlarm( short refNum, RcvAlarmPtr alarm );
- Pascal Mac : Procedure MidiSetRcvAlarm(refNum:integer; alarm:RcvAlarmPtr );
-
- Arguments of MidiSetRcvAlarm
- refNum : a 16-bit integer, the reference number of the application
- alarm : a RcvAlarmPtr, a pointer to a receive alarm routine or NIL to disable
- receive alarms.
-
- Prototype of a RcvAlarm routine
- C Mac ANSI : pascal void MyRcvAlarm (short refNum);
- Pascal Mac : procedure MyRcvAlarm (refNum:integer);
-
- Argument of a RcvAlarm routine
- refNum : a 16-bit integer, it is the reference number of the application.
-
- Example (ANSI C)
- A receive alarm that processes all the received events by adding to their date
- a one second delay.
-
- void OneSecDelay (short refNum)
- {
- MidiEvPtr e;
- long n;
-
- for ( n = MidiCountEvs(refNum); n > 0; —n )
- {
- e = MidiGetEv(refNum);/* Get an event from the fifo */
- Date(e) += 1000; /* Add 1000 ms to its date */
- MidiSend(refNum,e); /* Then send the event */
- }
- }
-
- ......
-
- MidiSetRcvAlarm(myRefNum,OneSecDelay); /* Install the receive alarm*/
-
- Note : one such procedure can be called repeatedly in the main event loop of the
- application, but for really accurate time control, it must be installed as a receive
- alarm with MidiSetRcvAlarm.
-
- Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
- Consequently, in C, all procedure passed as arguments of a MidiShare function must
- be declared as Pascal. In the previous exemple, OneSecDelay must be declared as
- : pascal void OneSecDelay (short refNum)
-
- æKY MidiSetSyncMode
- æT Function
- æDT MidiSetSyncMode( (unsigned)short mode);
- æC
-
- Description
- Set the synchronisation mode of MidiShare.
-
- Prototypes
- C Mac ANSI : pascal void MidiSetSyncMode (unsigned short mode);
- Pascal Mac : PROCEDURE MidiSetSyncMode (mode: integer);
-
- Arguments
- mode : an unsigned 16-bits word of struture : xa000000pppppppp.
- x (bit 15) is used to choose between internal synchronisation (x=0) and external
- synchronisation (x=1) a (bit 14) is used to choose between synchronisation on port
- p (a=0) and synchronisation on any port (a=1) bit 13:8 are reserved for future
- use and must be set to 0. p (bit 0:7) is the synchronisation port to be used when
- x=1 and a=0. When a=1 the port number is ignored, the first port with incomming
- MTC is used.
-
- Example 1 (ANSI C)
- Set the synchronisation to external, on any port.
-
- MidiSetSyncMode(MIDISyncExternal | MIDISyncAnyPort);
-
- Example 2 (ANSI C)
- Set the synchronisation to external, on port 18.
-
- MidiSetSyncMode(MIDISyncExternal | 18);
-
- Example 3 (ANSI C)
- Set the synchronisation to internal.
-
- MidiSetSyncMode(MIDISyncInternal);
-
- æKY MidiShare
- æT Function
- æDT Boolean myRet= MidiShare();
- æC
-
- Description
- Tests MidiShare code presence in memory by trying to recognise a special pattern.
- First of all, an application must make sure that MidiShare is in memory. This test
- is done thanks to the MidiShare function.
-
- Prototype
- C Mac ANSI : pascal Boolean MidiShare(void);
- Pascal Mac : Function MidiShare : boolean;
-
- Arguments
- none
-
- Result
- The result is true when MidiShare is loaded, false otherwise.
-
- Example (ANSI C)
- A DoNothing MidiShare application.
-
- #include MidiShare.h
- #include <stdio.h>
-
- short myRefNum;
-
- main()
- {
- if ( ! MidiShare() ) exit(1); /* Check MidiShare loaded */
- myRefNum = MidiOpen("Sample"); /* Ask for a reference number */
- if ( myRefNum < 1 ) exit(1); /* Check MidiOpen success */
- printf( "refNum : %i \n", myRefNum);/* Print the reference number*/
- MidiClose(myRefNum); /* And close */
- }
-
- Note for Mac users : MidiShare was originaly developed for Pascal on the Macintosh.
- Consequently, in C, all strings passed as arguments of a MidiShare function must
- be Pascal strings. In the previous exemple, one must write : myRefNum = MidiOpen("\pSample");
-
- æKY MidiSmpte2Time
- æT Function
- æDT long myRet= MidiSmpte2Time( (SmpteLocPtr)loc);
- æC
-
- Description
- Convert an SMPTE location to a time in millisecond.
-
- Prototypes
- C Mac ANSI : pascal long MidiSmpte2Time (SmpteLocPtr loc);
- Pascal Mac : FUNCTION MidiSmpte2Time (loc: SmpteLocPtr): longint;
-
- Arguments
- loc : a pointer to a TSmpteLocation record to be converted in milliseconds.
-
- Result
- a 32-bits time in milliseconds
-
- Description of a TSmpteLocation
- typedef struct TSmpteLocation *SmpteLocPtr;
- typedef struct TSmpteLocation
- {
- short format; // (0 : 24 f/s, 1 : 25 f/s,
- 2 : 30DF f/s, 3 : 30 f/s)
- short hours; // 0..23
- short minutes; // 0..59
- short seconds; // 0..59
- short frames; // 0..30 (according to format)
- short fracs; // 0..99 (1/100 of frames)
- } TSmpteLocation;
-
- Example (ANSI C)
- Gives the SMPTE location from its current format to 30 drop frame (format 2).
- TSmpteLocation myLoc;
- ...
- // we suppose here myLoc filled with an Smpte location
-
- MidiTime2Smpte( MidiSmpte2Time(&myLoc), 2, &myLoc);
-
- // now myLoc is filled with the same Smpte location but in 30 drop frame format.
-
- æKY MidiTask
- æT Function
- æDT MidiEvPtr myPtr= MidiTask(TaskPtr MyProc, long date, short refNum, long a1, long a2, long a3);
- æC
-
- Description
- On the same way as MidiDTask, MidiTask allows to realize a time delayed procedure
- call ; but on the reverse to MidiDTask, the call is achieved under interruption
- as soon as falling time is due.
-
- Prototype of MidiTask
- C Mac ANSI : pascal MidiEvPtr MidiTask (TaskPtr MyProc, long date,
- short refNum, long a1, long a2, long a3);
- Pascal Mac : Function MidiTask (MyProc:TaskPtr; date:longint;
- refNum:integer; a1,a2,a3: longint):MidiEvPtr;
-
- Arguments of MidiTask
- MyProc : a TaskPtr, it is the address of the routine to be called.
- date : a 32-bit integer, it is the date at which this call is scheduled.
- refNum : a 16-bit integer, it is the reference number of the application.
- a1,a2,a3 : are 32-bit integers left at the user’s disposal, as arguments to MyProc
-
- Result of MidiTask
- The result, a MidiEvPtr, is a pointer to a typeProcess MidiShare event. The result
- is NIL if MidiShare run out of memory.
-
- Prototype of MyProc
- C Mac ANSI : pascal void MyProc (long date, short refNum,
- long a1, long a2, long a3);
- Pascal Mac : procedure MyProc (date:longint; refNum:integer;
- a1,a2,a3: longint);
-
- Argument of MyProc
- date : a 32-bit integer, it is the date of the call .
- refNum : a 16-bit integer, it is the reference number of the application.
- a1,a2,a3 : are 32-bit integers that can be freely used.
-
- Example (ANSI C)
- Schedule a procedure Action() call 1000 ms ahead.
-
- MidiEvPtr myTask;
-
- myTask = MidiTask(Action,MidiGetTime()+1000,myRefNum, a1, a2, a3);
-
- Note : The result, in myTask, can be used to test the success of MidiTask. It can
- also be used by MidiForgetTask to try to "forget" a scheduled task before it happens.
-
- æKY MidiTime2Smpte
- æT Function
- æDT MidiTime2Smpte(long time,
- æC
-
- Description
- Convert a time in millisecond to an SMPTE location.
-
- Prototypes
- C Mac ANSI : pascal void MidiTime2Smpte (long time,
- short format, SmpteLocPtr loc);
- Pascal Mac : PROCEDURE MidiTime2Smpte (time: longint;
- format: integer; loc: SmpteLocPtr);
-
- Arguments
- time : a 32-bits time in milliseconds to convert in an Smpte location
- format : a 16-bits integer, the Smpte format to be used : (0 : 24 f/s, 1 : 25 f/s,
- 2 : 30DF f/s, 3 : 30 f/s) loc : a pointer to a TSmpteLocation record to be filled
- with the resulting Smpte location.
-
- Description of a TSmpteLocation
- typedef struct TSmpteLocation *SmpteLocPtr;
- typedef struct TSmpteLocation
- {
- short format; // (0 : 24 f/s, 1 : 25 f/s,
- 2 : 30DF f/s, 3 : 30 f/s)
- short hours; // 0..23
- short minutes; // 0..59
- short seconds; // 0..59
- short frames; // 0..30 (according to format)
- short fracs; // 0..99 (1/100 of frames)
- } TSmpteLocation;
-
- Example (ANSI C)
- Gives the SMPTE start location of the tape.
-
- TSyncInfo myInfo;
- TSmpteLocation myLoc;
-
- MidiGetSyncInfo(&myInfo);
- MidiTime2Smpte( MidiInt2ExtTime(myInfo.syncStart), myInfo.syncFormat,
- &myLoc);
-
- æKY MidiTotalSpace
- æT Function
- æDT long myRet= MidiTotalSpace();
- æC
-
- Description
- Gives the total space. MidiTotalSpace allows to know at any time the total number
- of cells allocated by the MidiShare memory manager at startup.
-
- Prototype
- C Mac ANSI : pascal long MidiTotalSpace(void);
- Pascal Mac : Function MidiTotalSpace : longint;
-
- Arguments
- none
-
- Result
- the result is a 32-bit integer, the total number of cells in the MidiShare memory
- manager.
-
- Example (ANSI C)
- Print informations about MidiShare memory space.
-
- void PrintMemInfo(void)
- {
- printf("MidiShare memory :\n");
- printf(" free space : %i cells\n", MidiFreeSpace());
- printf(" used space : %i cells\n", MidiTotalSpace() - MidiFreeSpace());
- printf(" total space : %i cells\n", MidiTotalSpace());
- }
-
- æKY MidiWriteSync
- æT Function
- æDT void* myPtr= MidiWriteSync( (void *)adrMem, (void *)val );
- æC
-
- Description
- Writes a 32-bit value to a variable only if the previous variable content was NIL.
- This function is non-interruptible in order to make easier communication between
- the application tasks that run at interrupt level. It can be used to implement
- some sort of "mail boxes" in conjunction of MidiReadSync
-
- Prototype
- C Mac ANSI : pascal void* MidiWriteSync( void *adrMem, void *val );
- Pascal Mac : Function MidiWriteSync( adrMem:univ ptr; val:univ ptr):ptr;
-
- Arguments
- adrMem : is the addresse of a variable to modifie.
- val : is a 32-bit value to write.
-
- Result
- The result is the previous content of the variable.
-
- Example (ANSI C)
- << to be supplied >>
-
- æKY typeActiveSens
- æC
- typeActiveSens (code 15)
-
- Event Description
- A Real Time ActiveSens message.
-
-
- Fields : ActiveSens events have no field.
-
-
- Example (ANSI C)
- Creates a ActiveSens event. Return a pointer to the event or NIL if there is no
- more memory space.
-
- MidiEvPtr ActiveSens ( long date, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeActiveSens ) )/* Allocate a new event. Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all*/
- Port(e) = port; /* kind of events */
- }
- return e;
- }
-
- æKY typeChanPress
- æC
- typeChanPress (code 6)
-
- Event Description
- A Channel pressure message with pressure value.
-
-
- Fields : ChanPress events have 1 field numbered 0 :
-
- 0 - A channel pressure value from 0 to 127. (Field size : 1 byte)
-
-
- Example (ANSI C)
- Creates a ChanPress event. Return a pointer to the event or NIL if there is no
- more memory space.
-
- MidiEvPtr ChanPress( long date, short press, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeChanPress ) )/* Allocate a new event. Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,press); /* Field particular to ChanPress */
- }
- return e;
- }
-
-
- æKY typeClock
- æC
- typeClock (code 10)
-
- Event Description
- A Real Time Clock message.
-
-
- Fields : Clock events have no field.
-
-
- Example (ANSI C)
- Creates a Clock event. Return a pointer to the event or NIL if there is no more
- memory space.
-
- MidiEvPtr Clock ( long date, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeClock ) )/* Allocate a new event. Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- }
- return e;
- }
- æKY typeContinue
- æC
- typeContinue (code 12)
-
- Event Description
- A Real Time Continue message.
-
-
- Fields : Continue events have no field.
-
- Example (ANSI C)
- Creates a Continue event. Return a pointer to the event or NIL if there is no more
- memory space.
-
- MidiEvPtr Continue ( long date, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeContinue ) )/* Allocate a new event. Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- }
- return e;
- }
-
- æKY typeCopyrigth
- æC
- typeCopyrigth (code 136)
-
- Event Description
- A copyright event (from the MidiFile 1.0 specification). This event cannot be sent
- to external Midi devices.
-
-
- Fields : typeCopyrigth events have a variable number of character fields.
-
- Example 1 (ANSI C)
- Creates a typeCopyrigth event from a character string. Return a pointer to the
- event or NIL if there is not enough memory space.
-
- MidiEvPtr Copyrigth ( long date, char *s, short chan, short port)
- {
- MidiEvPtr e;
- long c=0;
-
- if ( e = MidiNewEv(typeCopyrigth) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- for (c=0; *s; s++, c++) /* Build the event while counting */
- MidiAddField(e ,*s); /* the characters of
- the original string */
- if (c != MidiCountFields(e)) { /* Check the length of the event*/
- MidiFreeEv(e); /* if we run out of memory : free the */
- return 0; /* event and return NIL */
- }
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Convert a typeCopyrigth event into a character string. Assume s big enough.
-
- void GetText (MidiEvPtr e, char *s)
- {
- short c=0, i=0;
-
- c = MidiCountFields(e);
- while (i<c) *s++ = MidiGetField(e, i++);
- *s = 0;
- }
-
- æKY typeCtrl14b
- æC
- typeCtrl14b (code 131)
-
- Event Description
- A Control Change event with a controller number form 0 to 31 and a 14-bits value.
- When a typeCtrl14b event is sent to external Midi devices, actually two control
- change messages are sent, the first one for the MSB part of the value and the second
- one for the LSB part of the value. The message for the LSB part is sent only when
- the LSB part of the value is different from 0.
-
-
- Fields : Ctrl14b events have 2 fields numbered from 0 to 1 :
-
- 0 - A control number from 0 to 31. (Field size : 2 byte)
- 1 - A control value from 0 to 16383. (Field size : 2 byte)
-
- Example (ANSI C)
- Creates a CtrlChange event. Return a pointer to the event or NIL if there is no
- more memory space.
-
- MidiEvPtr CtrlChange14b( long date, short ctrl, short val, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeCtrl14b ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,ctrl); /* Fields particular to CtrlChange */
- MidiSetField(e,1,val);
- }
- return e;
- }
-
- æKY typeCtrlChange
- æC
- typeCtrlChange (code 4)
-
- Event Description
- A Control Change message with controller and value.
-
-
- Fields : CtrlChange events have 2 fields numbered from 0 to 1 :
-
- 0 - A control number from 0 to 127. (Field size : 1 byte)
- 1 - A control value from 0 to 127. (Field size : 1 byte)
-
- Example (ANSI C)
- Creates a CtrlChange event. Return a pointer to the event or NIL if there is no
- more memory space.
-
- MidiEvPtr CtrlChange( long date, short ctrl, short val, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeCtrlChange ) )/* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,ctrl); /* Fields particular to CtrlChange */
- MidiSetField(e,1,val);
- }
- return e;
- }
-
- æKY typeChanPrefix
- æC
- typeChanPrefix (code 142)
-
- Event Description
- A channel prefix event (from the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
-
- Fields : typeChanPrefix events have one field.
-
- 0 - A channel prefix number from 0 to 15. (Field size : 1 byte)
-
-
- Example (ANSI C)
- Creates a typeChanPrefix event. Return a pointer to the event or NIL if there is
- not enough memory space.
-
- MidiEvPtr ChanPrefix ( long date, short prefix)
- {
- MidiEvPtr e;
- long c=0;
-
- if ( e = MidiNewEv(typeChanPrefix)) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date;
- MidiSetField( e, 0, prefix);
- }
- return e;
- }
-
- æKY typeCuePoint
- æC
- typeCuePoint (code 141)
-
- Event Description
- A cue point event (from the MidiFile 1.0 specification). This event cannot be sent
- to external Midi devices.
-
-
- Fields : typeCuePoint events have a variable number of character fields.
-
-
- Example 1 (ANSI C)
- Creates a typeCuePoint event from a character string. Return a pointer to the event
- or NIL if there is not enough memory space.
-
- MidiEvPtr CuePoint ( long date, char *s, short chan, short port)
- {
- MidiEvPtr e;
- long c=0;
-
- if ( e = MidiNewEv(typeCuePoint)) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- for (c=0; *s; s++, c++) /* Build the event while counting the */
- MidiAddField(e ,*s);/* characters of the original string */
- if (c != MidiCountFields(e)) { /* Check the length of the event */
- MidiFreeEv(e); /* if we run out of memory : free the */
- return 0; /* event and return NIL */
- }
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Convert a typeCuePoint event into a character string. Assume s big enough.
-
- void GetText (MidiEvPtr e, char *s)
- {
- short c=0, i=0;
-
- c = MidiCountFields(e);
- while (i<c) *s++ = MidiGetField(e, i++);
- *s = 0;
- }
-
- æKY typeDProcess
- æC
- typeDProcess (code 129)
-
-
- Event Description
- DProcess events are automatically created by MidiDTask. They are used to realize
- time delayed procedure call. Once the scheduling date is due, the routine is not
- automatically executed, but stored in a special list. It is the application responsability
- to execute, one by one, those pending tasks using MidiExec1DTask.
-
-
- Fields : DProcess events have 4 fields numbered from 0 to 3 :
-
- 0 - a TaskPtr, the adress of the procedure to call. (Field size : 4 byte)
- 1 - the first argument of the procedure. (Field size : 4 byte)
- 2 - the second argument of the procedure. (Field size : 4 byte)
- 3 - the third argument of the procedure. (Field size : 4 byte)
-
-
- Example (ANSI C)
- Creates a DProcess event in the same way than MidiDTask.
-
- MidiEvPtr MakeDTask ( TaskPtr proc, long date, short refNum, long arg1,
- long arg2, long arg3)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeDProcess ) )/* Allocate a new event.
- Check not NIL */
- {
- MidiSetField(e, 0, (long)proc); /* Fill the 4 fields */
- MidiSetField(e, 1, arg1);
- MidiSetField(e, 2, arg2);
- MidiSetField(e, 3, arg3);
- MidiSendAt(refNum, e, date); /* and schedule the differed task*/
- }
- return e;
- }
-
- æKY typeEndTrack
- æC
- typeEndTrack (code 143)
-
- Event Description
- An end of track event (from the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
-
- Fields : typeEndTrack events have no field.
-
- Example (ANSI C)
- Creates a typeEndTrack event. Return a pointer to the event or NIL if there is
- not enough memory space.
-
- MidiEvPtr EndTrack ( long date )
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv(typeEndTrack)) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date;
- }
- return e;
- }
-
- æKY typeInstrName
- æC
- typeInstrName (code 138)
-
- Event Description
- An instrument name event (from the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
-
- Fields : typeInstrName events have a variable number of character fields.
-
- Example 1 (ANSI C)
- Creates a typeInstrName event from a character string. Return a pointer to the
- event or NIL if there is not enough memory space.
-
- MidiEvPtr InstrName ( long date, char *s, short chan, short port)
- {
- MidiEvPtr e;
- long c=0;
-
- if ( e = MidiNewEv(typeInstrName) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- for (c=0; *s; s++, c++) /* Build the event while counting the */
- MidiAddField(e ,*s);/* characters of the original string */
- if (c != MidiCountFields(e)) { /* Check the length of the event*/
- MidiFreeEv(e); /* if we run out of memory : free the */
- return 0; /* event and return NIL */
- }
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Convert a typeInstrName event into a character string. Assume s big enough.
-
- void GetText (MidiEvPtr e, char *s)
- {
- short c=0, i=0;
-
- c = MidiCountFields(e);
- while (i<c) *s++ = MidiGetField(e, i++);
- *s = 0;
- }
-
- æKY typeKeyOff
- æC
- typeKeyOff (code 2)
-
- Event Description
- A Note Off message with pitch and velocity.
-
- Fields : KeyOff events have 2 fields numbered from 0 to 1 :
-
- 0 - Pitch, a note number from 0 to 127. (Field size : 1 byte)
- 1 - Vel, a note velocity from 0 to 127. (Field size : 1 byte)
-
- Example 1 (ANSI C)
- Creates a KeyOff event. Return a pointer to the event or NIL if there is no more
- memory space. Fields are modified using MidiSetField instead of direct structure
- access.
-
- MidiEvPtr KeyOff( long date, short pitch, short vel, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeKeyOff ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,pitch); /* These fields are particular
- to KeyOff */
- MidiSetField(e,1,vel);
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Creates a KeyOff event. Return a pointer to the event or NIL if there is no more
- memory space. Fields are modified using direct structure access instead of MidiSetField.
-
- MidiEvPtr KeyKeyOff( long date, short pitch, short vel, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeKeyOff ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- Pitch(e) = pitch; /* These fields are particular to KeyOff*/
- Vel(e) = vel;
- }
- return e;
- }
-
- æKY typeKeyOn
- æC
- typeKeyOn (code 1)
-
- Event Description
- A Note On message with pitch and velocity.
-
- Fields : KeyOn events have 2 fields numbered from 0 to 1 :
-
- 0 - Pitch, a note number from 0 to 127. (Field size : 1 byte)
- 1 - Vel, a note velocity from 0 to 127. (Field size : 1 byte)
-
- Example 1 (ANSI C)
- Creates a KeyOn event. Return a pointer to the event or NIL if there is no more
- memory space. Fields are modified using MidiSetField instead of direct structure
- access.
-
- MidiEvPtr KeyOn( long date, short pitch, short vel, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeKeyOn ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,pitch);/* These fields are particular to KeyOn*/
- MidiSetField(e,1,vel);
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Creates a KeyOn event. Return a pointer to the event or NIL if there is no more
- memory space. Fields are modified using direct structure access instead of MidiSetField.
-
- MidiEvPtr KeyOn( long date, short pitch, short vel, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeKeyOn ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- Pitch(e) = pitch; /* These fields are particular to KeyOn */
- Vel(e) = vel;
- }
- return e;
- }
-
- æKY typeKeyPress
- æC
- typeKeyPress (code 3)
-
- Event Description
- A Polyphonic Key Pressure message with pitch and pressure.
-
- Fields : KeyPress events have 2 fields numbered from 0 to 1 :
-
- 0 - Pitch, a note number from 0 to 127. (Field size : 1 byte)
- 1 - Press, a key pressure from 0 to 127. (Field size : 1 byte)
-
- Example 1 (ANSI C)
- Creates a KeyPress event. Return a pointer to the event or NIL if there is no more
- memory space. Fields are modified using MidiSetField instead of direct structure
- access.
-
- MidiEvPtr KeyPress( long date, short pitch, short press, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeKeyPress ) )/* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,pitch); /* These fields are particular
- to KeyPress */
- MidiSetField(e,1,press);
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Creates a KeyPress event. Return a pointer to the event or NIL if there is no more
- memory space. Fields are modified using direct structure access instead of MidiSetField.
-
- MidiEvPtr KeyPress( long date, short pitch, short press, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeKeyPress ) )/* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- Pitch(e) = pitch; /* These fields are particular to KeyPress*/
- Vel(e) = press; /* Same byte than velocity */
- }
- return e;
- }
-
- æKY typeKeySign
- æC
- typeKeySign (code 147)
-
- Event Description
- A Key Signature event (form the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
- Fields : typeKeySign events have 2 fields :
-
- 0 - from -7 (7 flats) to 7 (7 sharps), (8-bits field)
- 1 - form 0 (major key) to 1 (minor key), (8-bits field)
-
- Example (ANSI C)
- Creates a Key Signature event. Return a pointer to the event or NIL if there is
- no more memory space.
-
- MidiEvPtr KeySign (long date, long sharpflats, long minor)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv(typeKeySign)) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date;
- MidiSetField(e, 0, sharpflats);
- MidiSetField(e, 1, minor);
- }
- return e;
- }
-
- æKY typeLyric
- æC
- typeLyric (code 139)
-
- Event Description
- A lyric event (from the MidiFile 1.0 specification). This event cannot be sent
- to external Midi devices.
-
- Fields : typeLyric events have a variable number of character fields.
-
- Example 1 (ANSI C)
- Creates a typeLyric event from a character string. Return a pointer to the event
- or NIL if there is not enough memory space.
-
- MidiEvPtr Lyric ( long date, char *s, short chan, short port)
- {
- MidiEvPtr e;
- long c=0;
-
- if ( e = MidiNewEv(typeLyric) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- for (c=0; *s; s++, c++) /* Build the event while counting the */
- MidiAddField(e ,*s);/* characters of the original string */
- if (c != MidiCountFields(e)) { /* Check the length of the event*/
- MidiFreeEv(e); /* if we run out of memory : free the */
- return 0; /* event and return NIL */
- }
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Convert a typeLyric event into a character string. Assume s big enough.
-
- void GetText (MidiEvPtr e, char *s)
- {
- short c=0, i=0;
-
- c = MidiCountFields(e);
- while (i<c) *s++ = MidiGetField(e, i++);
- *s = 0;
- }
-
- æKY typeMarker
- æC
- typeMarker (code 140)
-
- Event Description
- A marker event (from the MidiFile 1.0 specification). This event cannot be sent
- to external Midi devices.
-
- Fields : typeMarker events have a variable number of character fields.
-
- Example 1 (ANSI C)
- Creates a typeMarker event from a character string. Return a pointer to the event
- or NIL if there is not enough memory space.
-
- MidiEvPtr Marker ( long date, char *s, short chan, short port)
- {
- MidiEvPtr e;
- long c=0;
-
- if ( e = MidiNewEv(typeMarker)) /* Allocate a new event.
- Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- for (c=0; *s; s++, c++) /* Build the event while counting the */
- MidiAddField(e ,*s);/* characters of the original string */
- if (c != MidiCountFields(e)) { /* Check the length of the event*/
- MidiFreeEv(e); /* if we run out of memory : free the */
- return 0; /* event and return NIL */
- }
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Convert a typeMarker event into a character string. Assume s big enough.
-
- void GetText (MidiEvPtr e, char *s)
- {
- short c=0, i=0;
-
- c = MidiCountFields(e);
- while (i<c) *s++ = MidiGetField(e, i++);
- *s = 0;
- }
-
- æKY typeNonRegParam
- æC
- typeNonRegParam (code 132)
-
- Event Description
- A Non Registred Parameter event with a 14-bits parameter number and a 14-bits parameter
- value. When a typeNonRegParam event is sent to external Midi devices, actually
- four control change messages are sent, two to select the non-registerd parameter
- number, and two for the parameter value using the 14-bits data-entry controller.
-
- Fields : typeNonRegParam events have 2 fields numbered from 0 to 1 :
-
- 0 - A Non Registred Parameter number from 0 to 16383. (Field size : 2 byte)
- 1 - A parameter value from 0 to 16383. (Field size : 2 byte)
-
- Example (ANSI C)
- Creates a Non Registred Parameter event. Return a pointer to the event or NIL if
- there is no more memory space.
-
- MidiEvPtr NonRegParam( long date, short param, short val, short chan, short port)
- {
- MidiEvPtr e;
-
- if (e = MidiNewEv(typeNonRegParam)) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,param); /* Fields particular to NonRegParam */
- MidiSetField(e,1,val);
- }
- return e;
- }
-
- æKY typeNote
- æC
- typeNote (code 0)
-
- Event Description
- A note with pitch, velocity and duration. When a Note event is sent to external
- Midi devices, actually a NoteOn message is first sent followed, after a delay specified
- by the duration, by a NoteOn with a velocity of 0 to end the note.
-
- Fields : Note events have 3 fields numbered from 0 to 2 :
-
- 0 - Pitch, a note number from 0 to 127. (Field size : 1 byte)
- 1 - Vel, a note velocity from 0 to 127. (Field size : 1 byte)
- 2 - Dur, a note duration from 0 to 215-1. (Field size : 2 bytes)
-
- Example 1 (ANSI C)
- Creates a Note event. Return a pointer to the event or NIL if there is no more
- memory space. Fields are modified using MidiSetField instead of direct structure
- access.
-
- MidiEvPtr Note(long date,short pitch,short vel,short duration,short chan,short
- port) {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeNote ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,pitch); /* These fields are particular to Notes*/
- MidiSetField(e,1,vel);
- MidiSetField(e,2,dur);
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Creates a Note event. Return a pointer to the event or NIL if there is no more
- memory space. Fields are modified using direct structure access instead of MidiSetField.
-
- MidiEvPtr Note(long date,short pitch,short vel,short duration,short chan,short
- port) {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeNote ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- Pitch(e) = pitch; /* These fields are particular to Notes */
- Vel(e) = vel;
- Dur(e) = dur;
- }
- return e;
- }
-
- æKY typePitchWheel
- æC
- typePitchWheel (code 7)
-
- Event Description
- A Pitch Bender message with a 14 bits resolution.
-
- Fields : PitchWheel events have 2 fields numbered from 0 to 1 :
-
- 0 - LS 7-Bits of 14-bits pitch swing, from 0 to 127. (Field size : 1 byte)
- 1 - MS 7-Bits of 14-bits pitch swing, from 0 to 127. (Field size : 1 byte)
-
- Example (ANSI C)
- Creates a PitchWheel event with a parameter between -8192 and 8191. Return a pointer
- to the event or NIL if there is no more memory space.
-
- MidiEvPtr PitchWheel( long date, short wheel, short chan, short port)
- {
- const offset = 8192;
- const min = -8192;
- const max = 8191;
- MidiEvPtr e;
-
- wheel = (wheel>max) ? max : (wheel<min) ? min : wheel;
-
- if ( e = MidiNewEv( typePitchWheel ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,(wheel+offset) & 0x7F); /* LS-7bits Field */
- MidiSetField(e,1,(wheel+offset)>>7 & 0x7F); /* MS-7bits Field */
- }
- return e;
- }
-
- æKY typePrivate
- æC
- typePrivate (code 19 to 127)
-
- Event Description
- A private event with 4 fields which can be freely used by the application.
-
- Fields : Private events have 4 fields numbered from 0 to 3.
- Fields size : 4 bytes
-
- Example (ANSI C)
- <to be supplied>
-
- æKY typeProcess
- æC
- typeProcess (code 128)
-
- Event Description
- Process events are automatically created by MidiCall and MidiTask. They are used
- to realize time delayed procedure call. The procedure call is achieved under interrupts
- as soon as the scheduling date is due.
-
- Fields : Process events have 4 fields numbered from 0 to 3 :
-
- 0 - a TaskPtr, the adress of the procedure to call. (Field size : 4 byte)
- 1 - the first argument of the procedure. (Field size : 4 byte)
- 2 - the second argument of the procedure. (Field size : 4 byte)
- 3 - the third argument of the procedure. (Field size : 4 byte)
-
- Example (ANSI C)
- Creates a Process event in the same way than MidiTask.
-
- MidiEvPtr MakeTask ( TaskPtr proc, long date, short refNum, long arg1,
- long arg2, long arg3)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeProcess ) ) /* Allocate a new event.
- Check not NIL */
- {
- MidiSetField(e, 0, (long)proc); /* Fill the 4 fields */
- MidiSetField(e, 1, arg1);
- MidiSetField(e, 2, arg2);
- MidiSetField(e, 3, arg3);
- MidiSendAt(refNum, e, date); /* and schedule the task */
- }
- return e;
- }
-
- æKY typeProgChange
- æC
- typeProgChange (code 5)
-
- Event Description
- A Program Change message with a program number.
-
- Fields : ProgChange events have 1 field numbered 0 :
-
- 0 - A program number from 0 to 127. (Field size : 1 byte)
-
- Example (ANSI C)
- Creates a ProgChange event. Return a pointer to the event or NIL if there is no
- more memory space.
-
- MidiEvPtr ProgChange( long date, short prog, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeProgChange ) )/* Allocate a new event. Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,prog); /* Field particular to ProgChange */
- }
- return e;
- }
-
- æKY typeQuarterFrame
- æC
- typeQuarterFrame (code 130)
-
- Event Description
- A Midi time code quarter frame message with message type and value. These two fields
- are automatically assembled by MidiShare into one byte when the message is sent.
-
-
- Fields : QuarterFrame events have 2 fields numbered from 0 to 1 :
-
- 0 - A message type from 0=Frame count LSB nibble to 7=Hours count MS nibble. (Field
- size : 1 byte) 1 - A count nibble from 0 to 15. (Field size : 1 byte)
-
- Example (ANSI C)
- Creates a QuarterFrame event. Return a pointer to the event or NIL if there is
- no more memory space.
-
- MidiEvPtr QuarterFrame( long date, short type, short nibble, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeQuarterFrame ) )/* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- MidiSetField(e,0,type); /* Fields particular to QuarterFrame */
- MidiSetField(e,1,nibble);
- }
- return e;
- }
-
- æKY typeRegParam
- æC
- typeRegParam (code 133)
-
- Event Description
- A Registred Parameter event with a 14-bits parameter number and a 14-bits parameter
- value. When a typeRegParam event is sent to external Midi devices, actually four
- control change messages are sent, two to select the registred parameter number,
- and two for the parameter value using the 14-bits data-entry controller.
-
- Fields : typeRegParam events have 2 fields numbered from 0 to 1 :
-
- 0 - A Registred Parameter number from 0 to 16383. (Field size : 2 byte)
- 1 - A Registerd Parameter value from 0 to 16383. (Field size : 2 byte)
-
- Example (ANSI C)
- Creates a Registred Parameter event. Return a pointer to the event or NIL if there
- is no more memory space.
-
- MidiEvPtr RegParam( long date, short param, short val, short chan, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeRegParam ) )/* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- MidiSetField(e,0,param); /* Fields particular to RegParam */
- MidiSetField(e,1,val);
- }
- return e;
- }
-
- æKY typeReserved
- æC
- typeReserved (code 149 to 254)
-
- Event Description
-
- These events are reserved for future use.
-
- æKY typeReset
- æC
- typeReset (code 16)
-
- Event Description
- A Real Time Reset message.
-
- Fields : Reset events have no field.
-
- Example (ANSI C)
- Creates a Reset event. Return a pointer to the event or NIL if there is no more
- memory space.
-
- MidiEvPtr Reset ( long date, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeReset ) )/* Allocate a new event.
- Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- }
- return e;
- }
-
- æKY typeSeqName
- æC
- typeSeqName (code 137)
-
- Event Description
- A sequence name event (from the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
- Fields : typeSeqName events have a variable number of character fields.
-
- Example 1 (ANSI C)
- Creates a typeSeqName event from a character string. Return a pointer to the event
- or NIL if there is not enough memory space.
-
- MidiEvPtr SeqName ( long date, char *s, short chan, short port)
- {
- MidiEvPtr e;
- long c=0;
-
- if ( e = MidiNewEv( typeSeqName ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- for (c=0; *s; s++, c++) /* Build the event while counting the */
- MidiAddField(e ,*s);/* characters of the original string */
- if (c != MidiCountFields(e)) { /* Check the length of the event */
- MidiFreeEv(e); /* if we run out of memory : free the */
- return 0; /* event and return NIL */
- }
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Convert a typeSeqName event into a character string. Assume s big enough.
-
- void GetText (MidiEvPtr e, char *s)
- {
- short c=0, i=0;
-
- c = MidiCountFields(e);
- while (i<c) *s++ = MidiGetField(e, i++);
- *s = 0;
- }
-
- æKY typeSeqNum
- æC
- typeSeqNum (code 134)
-
- Event Description
- A Sequence number event (form the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
- Fields : typeSeqNum events have 1 field :
-
- 0 - Sequence number form 0 to 65535 (2-bytes field)
-
- Example (ANSI C)
- Creates a Sequence Number event. Return a pointer to the event or NIL if there
- is no more memory space.
-
- MidiEvPtr SeqNum( long date, short num, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeSeqNum) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- MidiSetField(e,0,num); /* the sequence number field */
- }
- return e;
- }
-
- æKY typeSMPTEOffset
- æC
- typeSMPTEOffset (code 145)
-
- Event Description
- An SMPTE Offset event (form the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
- Fields : typeSMPTEOffset events have 2 fields :
-
- 0 - Hours, minutes and seconds parts of the SMPTE Offset in seconds from 0 to
- 1048575 (20-bits field) 1 - Frames and 100ths of a frame part of the SMPTE Offset
- in 100ths of a frame form 0 to 4095 (12-bits field)
-
- Example 1 (ANSI C)
- Creates an SMPTE Offset event. Return a pointer to the event or NIL if there is
- no more memory space.
-
- MidiEvPtr SMPTEOffset(long hr, long mn, long sec, long frames, long subframes)
- {
- MidiEvPtr e;
-
- if (e = MidiNewEv(typeSMPTEOffset)) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = 0;
- MidiSetField(e, 0, hr*3600 + mn*60 + sec);
- MidiSetField(e, 1, (frames*100 + subframes));
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Read the different parts of an SMPTE Offset event.
-
- long GetHours (MidiEvPtr e)
- {
- return MidiGetField(e,0) / 3600;
- }
-
- long GetMinutes (MidiEvPtr e)
- {
- return MidiGetField(e,0) % 3600 / 60;
- }
-
- long GetSeconds (MidiEvPtr e)
- {
- return MidiGetField(e,0) % 60;
- }
-
- long GetFrames (MidiEvPtr e)
- {
- return MidiGetField(e,1) / 100;
- }
-
- long GetSubFrames (MidiEvPtr e)
- {
- return MidiGetField(e,1) % 100;
- }
-
- æKY typeSongPos
- æC
- typeSongPos (code 8)
-
- Event Description
- A Song Position Pointer message with a 14 bits location (unit : 6 Midi Clocks).
-
-
- Fields : SongPos events have 2 fields numbered from 0 to 1 :
-
- 0 - LS 7-Bits of 14-bits location, from 0 to 127. (Field size : 1 byte)
- 1 - MS 7-Bits of 14-bits location, from 0 to 127. (Field size : 1 byte)
-
- Example (ANSI C)
- Creates a SongPos event with a location in Midi clocks. The location is internaly
- divided by 6. Return a pointer to the event or NIL if there is no more memory space.
-
- MidiEvPtr SongPos( long date, short pos, short port)
- {
- MidiEvPtr e;
-
- pos = pos / 6;
-
- if ( e = MidiNewEv( typeSongPos) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- MidiSetField(e,0,pos & 0x7F); /* LS-7bits Field */
- MidiSetField(e,1,pos>>7 & 0x7F); /* MS-7bits Field */
- }
- return e;
- }
-
- æKY typeSongSel
- æC
- typeSongSel (code 9)
-
- Event Description
- A Song Select message with a song number.
-
- Fields : SongSel events have 1 field numbered 0 :
-
- 0 - A song number from 0 to 127. (Field size : 1 byte)
-
- Example (ANSI C)
- Creates a SongSel event. Return a pointer to the event or NIL if there is no more
- memory space.
-
- MidiEvPtr SongSel ( long date, short song, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeSongSel ) )/* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- MidiSetField(e,0,song); /* Field particular to SongSel */
- }
- return e;
- }
-
- æKY typeSpecific
- æC
- typeSpecific (code 148)
-
- Event Description
- A sequencer specific event (from the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
- Fields : typeSpecific events have a variable number of 8-bits fields.
-
- Example (ANSI C)
- Creates a typeSpecific event from an array of bytes. Return a pointer to the event
- or NIL if there is no more memory space.
-
- MidiEvPtr Specific ( long date, short len, Byte *p)
- {
- MidiEvPtr e;
- short c;
-
- if ( e = MidiNewEv( typeStream ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date;
- c = len;
- while (c--) MidiAddField(e,*p++);
- if (MidiCountFields(e) < len ) /* if event smaller than len then*/
- {
- MidiFreeEv(e); /* we run out of memory, free it */
- e = nil; /* and return nil */
- }
- }
- return e;
- }
-
- æKY typeStart
- æC
- typeStart (code 11)
-
- Event Description
- A Real Time Start message.
-
- Fields : Start events have no field.
-
- Example (ANSI C)
- Creates a Start event. Return a pointer to the event or NIL if there is no more
- memory space.
-
- MidiEvPtr Start ( long date, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeStart ) )/* Allocate a new event.
- Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- }
- return e;
- }
-
- æKY typeStop
- æC
- typeStop (code 13)
-
- Event Description
- A Real Time Stop message.
-
- Fields : Stop events have no field.
-
- Example (ANSI C)
- Creates a Stop event. Return a pointer to the event or NIL if there is no more
- memory space.
-
- MidiEvPtr Stop ( long date, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeStop ) )/* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- }
- return e;
- }
-
- æKY typeStream
- æC
- typeStream (code 18)
-
- Event Description
- Stream message are arbitrary stream of bytes sent by the MidiShare driver without
- any processing.
-
- Fields : Stream events have a variable number of fields.
-
- Example (ANSI C)
- Creates a Stream event from an array of short. Return a pointer to the event or
- NIL if there is no more memory space.
-
- MidiEvPtr Stream ( long date, short len, short *p, short port)
- {
- MidiEvPtr e;
- short c;
-
- if ( e = MidiNewEv( typeStream ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- c = len+1;
- while (--c) MidiAddField(e,*p++);
- if (MidiCountFields(e) < len ) /* if event smaller than len then*/
- {
- MidiFreeEv(e); /* we run out of memory, free it*/
- e = nil; /* and return nil */
- }
- }
- return e;
- }
-
- æKY typeSysEx
- æC
- typeSysEx (code 17)
-
- Event Description
- A System Exclusive message.
-
- Fields : SysEx events have a variable number of fields. The leading F0 and tailing
- F7 codes must not be included. They are automatically supplied by MidiShare. The
- channel field of the event is ORed with the first data byte after the manufacturer
- ID. This works for setting the channel of many system exclusive messages.
-
- Example (ANSI C)
- Creates a SysEx event from an array of short. Return a pointer to the event or
- NIL if there is no more memory space.
-
- MidiEvPtr SysEx ( long date, short len, short *p, short chan, short port)
- {
- MidiEvPtr e;
- short c;
-
- if ( e = MidiNewEv( typeSysEx ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- c = len+1;
- while (--c) MidiAddField(e,*p++);
- if (MidiCountFields(e) < len ) /* if event smaller than len then*/
- {
- MidiFreeEv(e); /* we run out of memory, free it */
- e = nil; /* and return nil */
- }
- }
- return e;
- }
-
- æKY typeTempo
- æC
- typeTempo (code 144)
-
- Event Description
- A tempo event (from the MidiFile 1.0 specification). This event cannot be sent
- to external Midi devices.
-
- Fields : typeTempo events have one field.
-
- 0 - A tempo value in microseconds/Midi quarter-note 0 to 127. (Field size : 4
- bytes)
-
- Example 1 (ANSI C)
- Creates a typeTempo event from a floating point tempo value in quarter-notes per
- minutes. Return a pointer to the event or NIL if there is not enough memory space.
-
- MidiEvPtr TempoChange ( long date, float tempo)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv(typeTempo)) /* Allocate a new event.
- Check not NIL* /
- {
- Date(e) = date;
- MidiSetField(e, 0, (long)(60000000.0 / tempo));
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Convert a tempo event in microseconds per quarter-note in a floating point tempo
- value in quarter-notes per minutes.
-
- float GetTempo (MidiEvPtr e)
- {
- return 60000000.0 / (float) MidiGetField(e,0);
- }
-
- æKY typeText
- æC
- typeText (code 135)
-
- Event Description
- A text event (from the MidiFile 1.0 specification). This event cannot be sent to
- external Midi devices.
-
- Fields : typeText events have a variable number of character fields.
-
- Example 1 (ANSI C)
- Creates a typeText event from a character string. Return a pointer to the event
- or NIL if there is not enough memory space.
-
- MidiEvPtr Text ( long date, char *s, short chan, short port)
- {
- MidiEvPtr e;
- long c=0;
-
- if ( e = MidiNewEv( typeText ) ) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date; /* These informations are common to all */
- Chan(e) = chan; /* kind of events */
- Port(e) = port;
- for (c=0; *s; s++, c++) /* Build the text event while counting */
- MidiAddField(e ,*s); /* the characters
- of the original string */
- if (c != MidiCountFields(e)) { /* Check the length
- of the text event */
- MidiFreeEv(e); /* if we run out of memory : free the */
- return 0; /* text event and return NIL */
- }
- }
- return e;
- }
-
- Example 2 (ANSI C)
- Convert a typeText event into a character string. Assume s big enough.
-
- void GetText (MidiEvPtr e, char *s)
- {
- short c=0, i=0;
-
- c = MidiCountFields(e);
- while (i<c) *s++ = MidiGetField(e, i++);
- *s = 0;
- }
-
- æKY typeTimeSign
- æC
- typeTimeSign (code 146)
-
- Event Description
- A Time Signature event (form the MidiFile 1.0 specification). This event cannot
- be sent to external Midi devices.
-
- Fields : typeTimeSign events have 4 fields :
-
- 0 - Numerator (8-bits field)
- 1 - denominator in power of two (8-bits field)
- 2 - Midi Clocks per metronome clicks (8-bits field)
- 3 - notated 32th of note per quarter-note (8-bits field)
-
- Example (ANSI C)
- Creates a Time Signature event. Return a pointer to the event or NIL if there is
- no more memory space.
-
- MidiEvPtr TimeSign (long date, long num, long denom, long click, long quarterDef)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv(typeTimeSign)) /* Allocate a new event.
- Check not NIL */
- {
- Date(e) = date;
- MidiSetField(e, 0, num);
- MidiSetField(e, 1, denom);
- MidiSetField(e, 2, click);
- MidiSetField(e, 3, quarterDef);
- }
- return e;
- }
-
- æKY typeTune
- æC
- typeTune (code 14)
-
- Event Description
- A Tune message.
-
- Fields : Tune events have no field.
-
- Example (ANSI C)
- Creates a Tune event. Return a pointer to the event or NIL if there is no more
- memory space.
-
- MidiEvPtr Tune ( long date, short port)
- {
- MidiEvPtr e;
-
- if ( e = MidiNewEv( typeTune ) )/* Allocate a new event. Check not NIL*/
- {
- Date(e) = date; /* These informations are common to all */
- Port(e) = port; /* kind of events */
- }
- return e;
- }
-